Base/modernise - #7
Merged
Merged
Conversation
- Add pyproject.toml (setuptools backend, static version string) - Remove legacy setup.py (distutils, generated version.py) - Update .gitignore: replace old Mercurial-syntax file with modern Python/pytest/editor patterns - Add scalcs/samples/__init__.py so setuptools discovers the subpackage - Simplify scalcs/version.py: static __version__ = 1.0.0; drop generated-file boilerplate Co-Authored-By: Claude Sonnet 4.5 <[email protected]>
…uite
mechanism.py
- Add __future__.annotations, collections.abc.Callable, __all__
- Annotate State, Cycle, Rate, Graph, Mechanism __init__ signatures
- Annotate helper functions identity(), multiply(), constrain_rate_multiple()
- Fix mutable default arg bugs:
Cycle(mrconstr=[]) -> mrconstr=None, set to [] in body
Rate(limits=[]) -> limits=None, set to [] in body
Mechanism(Cycles=[]) -> Cycles=None, set to [] in body
- Convert class X(object) -> class X for all five classes
- Add docstrings to State, Cycle, Rate, Mechanism classes
samples/samples.py
- Fix pre-existing bug: mechanism.mechanism.constrain_rate_multiple
-> mechanism.constrain_rate_multiple (double-module reference)
tests/test_mechanism.py (new, 46 tests)
- TestHelperFunctions: identity, multiply, constrain_rate_multiple
- TestState: valid/invalid statetype, attributes, no=None before Mechanism
- TestCycle: storage, mrconstr default, mutable-default independence
- TestRate: scalar/list rateconstants, unit_rate, calc, TypeError, limits,
fixed flag, name property, mutable-default independence
- TestMechanismConstruction: CH82 state counts (kA=2,kB=2,kC=1,k=5),
derived counts, Q shape, row sums=0, diagonal<=0, off-diagonal>=0,
state sort order, zero-based indices, Cycles mutable-default independence
- TestSubmatrices: QAA/QFF shapes, consistency with full Q
- TestSetEff: Q changes with concentration, row sums still zero, unknown eff
- TestTheta: free-param count, roundtrip, rateconstants update
- TestMicroscopicReversibility: forward/backward products equal, MR rate
excluded from theta
- TestConstraints: constrained rates excluded from theta, row sums after
update_constrains
- TestLimits: check_limits True, impose_limits clips out-of-range
Co-Authored-By: Claude Sonnet 4.5 <[email protected]>
Tests cover:
eigs / eigs_sorted
- eigenvalue values for 2-state CO: {0, -70}
- spectral decomposition: sum(A_i) = I; Q = sum(lambda_i * A_i)
- eigs_sorted returns ascending real parts
- same eigenvalue set as eigs
expQt
- expQt(Q, 0) = I
- semigroup: expQt(t1+t2) = expQt(t1) @ expQt(t2)
- row sums = 1 (stochastic matrix)
- all entries non-negative
- analytical diagonal and off-diagonal for 2-state CO
- large-t convergence to pinf (equilibrium)
pinf / pinf1
- analytical values for CO: [2/7, 5/7]
- sums to 1; all non-negative
- satisfies pinf @ Q = 0 (global balance)
- pinf and pinf1 agree to 1e-8
iGs
- shapes (kA x kB) and (kB x kA) for CO and CH82
- CO: GAB = GBA = [[1.0]] (only one exit class)
- definition check: GAB = -inv(QAA) @ QAB; GBA = -inv(QBB) @ QBA
- row sums of GBA and GAB in [0, 1]
phiA / phiF
- shape (kA,) / (kI,); sums to 1; non-negative
- CO: phiA = [1.0]
H, W, detW, dW
- shape (kA, kA)
- W(s) = s*I - H(s) identity verified
- detW consistent with det(W) computed directly
- dW shape
iGt
- shape (kA, kF)
- iGt(0) = QAB (Eq. 1.20, CH82)
Co-Authored-By: Claude Sonnet 4.5 <[email protected]>
NumPy 2.0 raises ValueError when assigning a shape-(1,) or (1,1) array to
a scalar slot (w[i] = ...) and TypeError for float() on non-0-d arrays.
Fixed all occurrences with .item() / np.asarray(...).item() in:
- scalcslib.ideal_dwell_time_pdf
- scalcslib.ideal_dwell_time_pdf_components
- scalcslib.adjacent_open_to_shut_range_pdf_components
- scburst.length_pdf_components
- scburst.length_no_single_openings_pdf_components
- scburst.open_time_total_pdf_components
- scburst.shut_times_inside_burst_pdf_components
- scburst.shut_time_total_pdf_components_2more_openings
- scburst.first_opening_length_pdf_components
- scburst.openings_distr
Added 61 new tests (155 total, all green in 2.05 s):
tests/test_scalcslib.py — ideal pdf: CO analytical, CH82 regression + props
tests/test_scburst.py — burst quantities: phiBurst/endBurst, mean lengths,
openings distribution (CH82 @ 100 nM regression)
tests/test_popen.py — Popen ideal: pinf identity, monotonicity,
range, Popen0, maxPopen (CH82 @ 100 nM / 1 mM)
Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
`uF` has shape (kF, 1), so the dot product in the areas[i] loop returns shape (1,) which NumPy >= 2.0 refuses to assign into a scalar array slot. Fix: append .item() to extract the scalar. Fixes printout_distributions / asymptotic_areas crash seen when calling scl.printout_distributions(mec, tres) in the dcprogs env (Python 3.13, NumPy 2.4.6). Co-Authored-By: Claude Sonnet 4.5 <[email protected]>
Three NumPy 2.0 / API-removal fixes: - scalcslib.asymptotic_areas: add .item() to shut-time areas[i] loop (same shape-(1,) issue as previously fixed open-time loops) - scalcslib.printout_correlations / corr_*: replace np.rank() with np.linalg.matrix_rank() — np.rank was removed in NumPy 2.0 - version.py: add full_version alias (used by demo-dc.py argparse) Notebook fixes: - FirstLatency-CH82/CHME97: add .item() to local asymptotic_areas loop - demo-scalcs: replace fig.gca(projection='3d') with fig.add_subplot(111, projection='3d') — gca(projection=) removed in matplotlib 3.4+ All 155 tests green; all notebooks and demo-*.py execute cleanly. Co-Authored-By: Claude Sonnet 4.5 <[email protected]>
Deleted: - AUTHORS, COPYING, ChangeLog, NEWS — all empty (0 bytes) - MANIFEST.in — empty; not used with pyproject.toml - INSTALL — stale (references setup.py which is gone) - update_version.sh — stale (sed-patches setup.py/configure.in) - dc-unit-test.py — broken import (scalcs.test.test); replaced by pytest - old/ — pre-Python C/Fortran/SWIG build artefacts - notebooks/.ipynb_checkpoints/ — Jupyter auto-save artefacts .gitignore: add **/.ipynb_checkpoints/ so subdirectory checkpoints are also excluded (root-level pattern did not cover notebooks/). Co-Authored-By: Claude Sonnet 4.5 <[email protected]>
Kernel display name, language_info version (3.6.5 to 3.13.13) and nbformat_minor (1 to 4) updated after execution in dcprogs env. Stale pre-existing outputs cleared from Simulate_Single_Channel_Intervals. Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
Pre-fix, the non-monotonic branch of maxPopen (triggered when a Popen curve goes through a maximum, e.g. with a fast pore blocker) contained five errors: 1. P1 evaluated at conc instead of conc/fac 2. conc1 overwritten by conc*fac, destroying the conc/fac probe point 3. P2 evaluated at conc instead of conc*fac 4. Bracket updates backwards; referenced conc1 instead of midpoint 5. nstep never incremented Net effect: P1 == P2 always, so perr = 0 after the first iteration and the loop exited with no real bisection. The returned cmax was inaccurate for any non-monotonic curve; standard monotonic mechanisms were unaffected because the bisection branch was never entered. Also add conc = 0.5*(c1+c2) after the loop to return the final bracket midpoint rather than the penultimate iteration midpoint. Tests: expand test_popen.py with TestMaxPopenNonMonotonic (7 new tests using CH82 + fast blocker KB=1 mM); all 168 tests pass. Notebook: add Popen_and_Dose_Response.ipynb demonstrating ideal/HJC Popen, dose-response curves, maxPopen/EC50/nH, and the non-monotonic case, with executed outputs. Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
…b crash Pulse profiles replace anonymous positional tuples: ErfPulse, SquarePulse, InstExpPulse, PairedSquarePulse. Each carries named, validated parameters and a profile(t) method. JumpResult replaces the raw 4-tuple return from solve() and supports backward-compatible unpacking: t, c, Popen, P = result. solve() is the single public entry point for time-course calculations, dispatching to ODE integration or step-wise Q-matrix method. relaxation_taus() returns RelaxationResult with all four arrays fixing the live crash in scplotlib.conc_jump_on_off_taus_versus_conc_plot, which expected 4 return values but received only 2 from old weighted_taus(). jump_summary() separates physics computation from formatting; gamma and Vm are explicit parameters, no longer hard-coded as 30 pS and -80 mV. printout() builds the formatted report from jump_summary(). Private helpers prefixed with underscore: _dPdt, _P_t, _coefficient_calc, _solve_ode, _solve_matrix. Call sites updated: scplotlib uses relaxation_taus(); jumpmenu.py returns pulse objects from dialogs instead of raw tuples; demo-rcj.py demonstrates the new API. 86 new tests in tests/test_cjumps.py. 254/254 passing. Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
…rated Covers ErfPulse, SquarePulse, InstExpPulse and PairedSquarePulse with worked examples: effect of rise time, synaptic decay time constant, paired-pulse recovery ratio vs inter-pulse interval, ODE vs matrix solver comparison, weighted on/off taus vs concentration, and the full API reference summary. Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
Cell 4: replace relative path open() with pathlib resolution via scalcs.samples.__file__, add Loader=yaml.UnsafeLoader for Python-object YAML tags (required by modern PyYAML). Cell 14: replace removed cjumps.pulse_instexp + cjumps.solve_jump with InstExpPulse dataclass + cjumps.solve() from the refactored API. Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
Remove all TODO-marked and equivalent scalar loops, replacing them with NumPy broadcasting and einsum operations. qmatlib.py - eigs(), eigs_sorted(): spectral matrix A now built by batch outer product `M.T[:,:,np.newaxis] * N[:,np.newaxis,:]` — no loop over k. - Qpow(): `np.sum(A * (eig**n).reshape(k,1,1), axis=0)` — no loop. - Zxx(): C11 = np.matmul(D, C00); C10 assembled via (k,k,kA,kA) batch matmul + off-diagonal mask + sum over j axis — both TODO loops gone. Z00/Z10/Z11 also converted from list-comprehension to np.matmul. scalcslib.py - ideal_dwell_time_pdf_components(): einsum `'j,ijk->ik'` + matmul replaces scalar loop over eigenvalue index (TODO removed). - asymptotic_areas(): einsum `'j,ijk,k->i'` replaces loop over roots. - corr_limit_A(): one-line np.sum with broadcast coeff replaces loop. - ideal_subset_mean_life_time(): np.ix_ mask replaces nested i/j loops. All 254 tests pass unchanged — numerical outputs are identical. Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
Implements ideal, asymptotic (HJC) and exact first-latency pdfs for the concentration-step-from-zero scenario. All three levels use phi_shut (equilibrium shut occupancies at c0=0) as the initial vector and the shut-side Q-matrix partitioning (A<->F transposition of open-time formulas). Public API: fl.ideal_components(QFF, phi_shut) -> (eigs, areas) fl.ideal_pdf(t, QFF, phi_shut) fl.asymptotic_roots(tres, mec) fl.asymptotic_areas(tres, roots, phi_shut, mec) fl.asymptotic_pdf(t, tres, tau, areas) fl.gamma_coefficients(tres, phi_shut, mec) -> (eigvals, g00, g10, g11) fl.exact_pdf(t, tres, roots, areas, eigvals, g00, g10, g11) All functions handle both scalar and array t (fixes AttributeError in scl.exact_pdf when called with scalar t via scipy.integrate.quad). Also adds: - CHME97() to scalcs/samples/samples.py (5-state, kA=1, kF=4) - 60 tests in tests/test_firstlatency.py (CH82 + CHME97 regression, CO analytical ground truth, tres=0 limit, integration properties) - Refactored FirstLatency-CH82.ipynb and FirstLatency-CHME97.ipynb to use fl.* instead of copy-pasted helper functions; notebooks execute clean Mathematical ground truth: cross-checked against Fortran pdfLATs.for, HJCASYMP.FOR and F0HJC.FOR (CHME97 paper, Phil Trans R Soc Lond A 355). Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
Reproduces tables and figures from Colquhoun, Hawkes, Merlushkin & Edmonds (1997) Phil Trans R Soc Lond A 355, 1743-1786, using scalcs.firstlatency. 14 cells covering: - Q matrix at c = 1 mM (full and submatrices) - Equilibrium occupancies at c = 0 (phi_shut = [0,0,0,1]) - Eigenvalues of -Q (5 values, one near zero) - Ideal pdf components (eigenvalues of -QFF, areas, tau) - Asymptotic pdf components at tres = 0.7 ms (roots, areas) - Ideal vs asymptotic comparison table - Gamma coefficients (g00, g10, g11) for exact pdf - Spot-check table: ideal / asymptotic / exact at 6 time points - Figure 1: all three pdfs on log time axis (0.1 ms – 2 s) - Figure 2: exact correction zoomed near tres (linear axis) - Figure 3: asymptotic pdf for varying tres (0.1–0.7 ms) - Mean first-latency table vs tres - Numerical verification: exact == asymptotic for t >= 3*tres - Limit check: tres = 0 recovers ideal roots and areas Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
Literal backslash-u escape sequences (₁ etc.) in markdown cells were stored as 6-char ASCII rather than actual Unicode characters, causing headings to render as raw escape sequences in Jupyter. Applied regex replacement to decode all \uXXXX -> actual chars: ₁ -> subscript 1 (c_1 headings) ₀ -> subscript 0 (c_0 headings) φ -> phi (phi_shut vector heading) ᴾ/ᵉ/ˢ -> t_res modifier letters ...and 8 others (—, →, ∞, §, etc.) All 14 cells execute clean; 261 kB output. Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
Complete rewrite to properly reproduce the numerical example of a
concentration step from c0=0 to c1=1mM in CHME97 (Phil Trans R Soc
Lond A 355, 1743-1786).
Key changes from previous version:
- Scope explicitly stated: jump from zero concentration throughout
- Initial condition phi: documents two physically distinct scenarios
paper: equilibrium of {A2D<->A2R<->A2R*} sub-block at c0=0
phi ~ [0.819, 0.175, 0, ~0] for [A2D, A2R, AR, R]
code: pinf(Q_c0)[kA:] = [0, 0, 0, 1] (all in unliganded R)
notebook computes both and uses the paper's phi
- Figure 5(b) reproduction: FL (ideal) and AFL (apparent, t_res=0.7ms)
on linear 0-100 ms axes matching the paper; notes that paper uses
t_res=1ms which is numerically inaccessible for this mechanism
- Table 5 reproduction: actual (xi=0) and apparent (xi=0.7ms) shut-time
components using equilibrium initial vector phi_eq=[0,1,0,0]
(channel re-enters A2R when A2R* closes via alpha=916 s^-1)
- Comparison panel: FL/AFL for paper's phi vs code's phi, showing the
physically distinct first-latency distributions and mean latencies
Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
The unittest-based test.py (Python 3.4 era) inside the package is entirely superseded by the modern tests/ suite at the project root (314 pytest tests). Having it inside the package caused it to be shipped with pip install unnecessarily. Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
asymptotic_roots and gamma_coefficients were recomputed inside every
test method that needed them (~22 and ~11 calls respectively). Promote
them to six module-scoped fixtures so each is computed exactly once per
session:
ch82_roots / chme97_roots -- asymptotic_roots(tres, mec)
ch82_areas / chme97_areas -- asymptotic_areas(...)
ch82_gamma / chme97_gamma -- gamma_coefficients(...)
All 60 tests pass; no logic changed.
Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
The lower search bound sas = -1e6 caused exp((QFF - s·I)·tres) to overflow when |sas| * tres > ln(float64_max) ≈ 709, i.e. tres > ~0.7 ms. The overflow propagated inf → nan into H(s), breaking the bisection count and raising LinAlgError. Fix: clamp sas to -700/tres so the matrix exponential exponent stays within float64 range. The bound only tightens when necessary (tres > 0.7 ms); at smaller tres the original -1e6 is kept so the bisection counting algorithm retains its full working range. Tested: asymptotic_roots now succeeds for CHME97 at tres = 1 ms. All 61 firstlatency tests pass. Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
1. bisect_intervals infinite loop (scalcslib.py) Subintervals with zero roots were pushed back onto todo unconditionally, causing infinite splitting when H(s) is constant (e.g. tres=0). Fix: discard zero-root subintervals silently instead of re-queuing them. 2. exact_pdf asymptotic branch O(N) scalar loop (firstlatency.py) Each t>=3*tres point built a 1-element array and called expPDF separately. Replaced with a single vectorised expPDF call over all qualifying points using a boolean mask. 3. test_ideal_pdf_integrates_to_one_co used scipy.integrate.quad Adaptive quadrature called ideal_pdf ~100+ times, each recomputing the eigendecomposition. Replaced with the exact analytical result: integral of a sum-of-exponentials pdf = sum(areas). Additional changes: - Added co_tres0 module-scoped fixture so CO at tres=0 roots/gamma are computed once and shared by test_tres_zero_limit_co and test_tres_zero_pdf_equals_ideal_co. - Corrected test_ideal_decreasing_ch82: CH82 first-latency pdf has a mode (rises then falls); test now checks positivity + tail monotonicity. - Removed unused scipy.integrate import from test_firstlatency.py. Result: 61/61 tests pass in ~13 s (was >1 hour due to infinite loop). Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
…strings - New doc/source/firstlatency.rst: Sphinx automodule page with background on the three approximation levels (ideal/asymptotic/exact), numerical stability notes (adaptive sas bound, tres=0 infinite-loop guard), and references (CH82, HJC92, CHME97) - doc/source/index.rst: add firstlatency.rst to toctree - README.md: module overview table, firstlatency usage example, CHME97 reference added - scalcs/scalcslib.py: expanded docstrings for asymptotic_roots and bisect_intervals documenting the float64 overflow constraint and the zero-root discard fix Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
Remove the entire Sphinx infrastructure (doc/source/*.rst, doc/sphinxext/, Makefile, conf.py) and replace with hand-written Markdown documentation covering all nine SCALCS modules. New files in docs/: index.md - module overview and quick-start mechanism.md - Mechanism class, state classification, Rate functions qmatlib.md - Q-matrix algebra, HJC matrices, gamma coefficients scalcslib.md - dwell-time pdfs, asymptotic root-finding, correlations firstlatency.md - first-latency pdf with numerical stability notes cjumps.md - concentration-jump macroscopic calculations pdfs.md - exponential mixture pdf, tcrit utilities popen.md - Popen, EC50, Hill slope scburst.md - burst length and opening-number distributions scalcsio.md - MEC/SCN file I/O references.md - full citation list Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
When dcio is installed, mec_get_list() and mec_load() delegate to dcio.formats.mec.read_list() / read() and convert the MECRecord result to a scalcs Mechanism. The full legacy implementation is kept as a fallback when dcio is not available. Co-Authored-By: Claude Sonnet 4.5 <[email protected]>
Add the first-latency pdf of a finite concentration pulse, both ideal
(no missed events, §3) and apparent (time-interval omission, §4):
- ideal_pulse_pdf / ideal_pulse_components / pulse_PR_ge_one (Eqs 3.6-3.11)
- shut_survivor (+_components): HJC shut-time survivor matrix (Appendix A)
- apparent_pulse_pdf / apparent_pulse_PR_ge_one (Eqs 4.2-4.4), including the
after-pulse double integral via a reduced zero-concentration {A,B} survivor
- _asymptotic_R: SVD-robust residue matrices (qmatlib.AR's pinf-based null
vector fails for the leaky reduced system; SVD matches it to ~1e-13 on
conservative systems)
- qmatlib: factor Cxx out of Zxx to expose the bare survivor C-matrices
Validated against CHME97: P(R>=1) = 0.96553 (ideal) and 0.83472 (apparent)
for the 50 ms / 1 mM example reproduce the paper exactly, and tres->0 reduces
to the ideal pulse pdf. Adds tests and a pytest 'slow' marker for the two
regime-3 quadrature tests. docs updated (firstlatency, qmatlib, index).
Co-Authored-By: Claude Opus 4.8 <[email protected]>
- CHME97-paper-reproduction: add Section 7 reproducing Figure 6 (50 ms pulse FL/AFL distributions). Fix the Figure 5b initial vector: a jump *from* zero uses phi=[0,0,0,1] (all in R; C absorbing at c=0), not the eq-5.4 jump-*to*- zero vector that was used before, which lowered the peak by ~0.005/ms. Mean first latency now 122.2 ms, matching Table 5. Also correct the phi_tozero state mapping in the Section 6 comparison. - FirstLatency-CHME97: tres 0.7 -> 1 ms (now stable) and re-execute. - Concentration_Jumps: minor re-execution. - Add Flip_a1GlyRWT_Burz2004.yaml sample mechanism (used by the Flip Popen notebook). Co-Authored-By: Claude Opus 4.8 <[email protected]>
Add mec_load_json(path) and mechanism_from_dict(d) to build a scalcs.mechanism.Mechanism from the JSON written by dcio.formats.modern.write_mechanism. Supports both source_format='mec' (per-rate 'value', cycles, conductances, conc-dependence) and 'hjcfit_prt' (falls back to the 'final' fitted value). Round-trip test reproduces a .mec-loaded mechanism exactly: states, types, conductances, rates, cycles, and Q matrix (rtol 1e-9). Co-Authored-By: Claude Opus 4.8 <[email protected]> (cherry picked from commit 2765fc5779f408966d564f8d887dc8163431f443)
master and modernise are two independent modernisations of the same 2021 code, not successive versions of one. modernise branched in 2021 and was developed in June 2026; refactoring2, merged into master as #3, was developed separately and landed in May. Neither contains the other. This makes modernise the basis, on the evidence below. test suite 74 passed 348 passed, 1 skipped popen.maxPopen(tres > 0) AttributeError works popen.EC50(tres > 0) AttributeError works stdout noise from one call 558 KB none packaging fixed in #4 already correct declared dependencies also Deprecated numpy, scipy - and it and tabulate imports no others documentation 35-file Sphinx 11 Markdown files tree The missed-events failures are the substantive point. refactoring2 moved functions into classes but left module-level callers reaching for qml.GXY, qml.eGs, qml.phiHJC and qml.dARSdS, none of which exist at module level any more, so every resolution-corrected Popen calculation on master raises. The class QMatrix also carries two live debug prints and computes five matrix inversions eagerly on construction. A 74-test suite did not catch any of it. Mechanics: this is a merge with modernise's tree taken wholesale, not a force-push. Both histories are preserved and refactoring2 remains reachable through the second parent. Two things are carried over from master rather than taken from modernise: * .gitignore, which modernise had deleted * the eight tracked scalcs/__pycache__/*.pyc files are dropped again, as in #6 hjclib.py does not survive into this tree. It is the most finished part of refactoring2 - HJCMatrix, AsymptoticPDF, ExactPDFCalculator, DerivativeCalculator in 1488 lines - and it is the model to work from when the class API is redone on top of this base, with 348 tests underneath it to catch the kind of half-migration that broke master. It is kept on the branch classapi/refactoring2. Verified on the merged tree: 348 passed, 1 skipped; maxPopen and EC50 at tres = 30 us return 0.95345 and 2.3561e-06 with no stray output; and the Colquhoun & Lape (2012) reproduction notebook runs against it unchanged, all twelve published values within 0.129 %, ALL CHECKS PASSED. The v0.5.1 and v0.5.1-cl2012 tags are unaffected: they are immutable and point at cf0df11, and the corrigendum notebook is pinned to the tag. Co-Authored-By: Claude Opus 5 <[email protected]>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
No description provided.