File size: 2,164 Bytes
64c992d
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
"""Structural checks for the shipped symmetrized scaling tables (data/scaling_factors/).

These run on the small CSVs that ship in git, so they need no download. The file is named
test_scaling_factors_export.py (not test_scaling_factors.py) on purpose: analysis/code/ already has a
test_scaling_factors.py, and pytest's default import mode cannot collect two test modules that share
a basename.
"""
import os
import sys

import pandas as pd
import pytest

HERE = os.path.dirname(os.path.abspath(__file__))
sys.path.insert(0, HERE)

import scaling_factors_reader as R  # noqa: E402


def test_both_tables_load_with_expected_shape_and_columns():
    tables = R.load_symmetrized_tables()
    assert set(tables) == {"H", "C"}
    for nucleus, df in tables.items():
        assert df.shape == (12, 3), nucleus
        assert list(df.columns) == ["intercept", "stationary", "pcm"], nucleus
        assert "chloroform" in df.index
        assert df.notnull().all().all(), nucleus


def test_slopes_are_negative_and_intercepts_in_range():
    tables = R.load_symmetrized_tables()
    # the gas-phase (stationary) slope is a shielding-to-shift conversion, always near -1
    for nucleus, df in tables.items():
        assert (df["stationary"] < 0).all(), nucleus
    # proton reference intercept sits near a bare-proton shielding (~31 ppm), carbon much higher
    assert 25 < tables["H"]["intercept"].mean() < 35
    assert 150 < tables["C"]["intercept"].mean() < 200


def test_predict_shift_uses_the_documented_linear_formula():
    # a synthetic one-row table with round coefficients, so the expected value is hand-computed
    # independently of predict_shift's own arithmetic (this catches a sign flip or a swap of the
    # stationary/pcm coefficients, which recomputing the same formula inline would not):
    #   10 + (-1)*5 + 2*3 = 11
    table = pd.DataFrame({"intercept": [10.0], "stationary": [-1.0], "pcm": [2.0]}, index=["x"])
    table.index.name = "solvent"
    assert R.predict_shift(table, "x", shielding=5.0, correction=3.0) == pytest.approx(11.0)


def test_reader_rejects_unknown_nucleus():
    with pytest.raises(ValueError):
        R._csv_path("X")