Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 12 additions & 1 deletion .claude/commands/swp/test/audit.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,12 @@ Detects anti-patterns BEFORE they cause test failures.

| ID | Pattern | Severity | Count (baseline) |
|----|---------|----------|------------------|
| swp-test-001 | `assert X is not None` (trivial) | warning | 133 |
| swp-test-001 | `assert X is not None` (trivial) | warning | 74 |
| swp-test-002 | `patch.object` without `wraps=` | warning | 76 |
| swp-test-003 | Assert without error message | info | - |
| swp-test-004 | `plt.subplots()` (verify cleanup) | info | 59 |
| swp-test-006 | `len(x) > 0` without type check | info | - |
| swp-test-009 | `isinstance(X, object)` (disguised trivial) | warning | 0 |

### Good Patterns to Track (Adoption Metrics)

Expand Down Expand Up @@ -77,6 +78,15 @@ mcp__ast-grep__find_code(
language="python",
max_results=30
)

# 5. Disguised trivial assertion (swp-test-009)
# isinstance(X, object) is equivalent to X is not None
mcp__ast-grep__find_code(
project_folder="/path/to/SolarWindPy",
pattern="isinstance($OBJ, object)",
language="python",
max_results=50
)
```

**FALLBACK: CLI ast-grep (requires local `sg` installation)**
Expand Down Expand Up @@ -163,6 +173,7 @@ This skill is for **routine audits** - quick pattern detection before/during tes
| Anti-Pattern | Fix | TEST_PATTERNS.md Section |
|--------------|-----|-------------------------|
| `assert X is not None` | `assert isinstance(X, Type)` | #6 Return Type Verification |
| `isinstance(X, object)` | `isinstance(X, SpecificType)` | #6 Return Type Verification |
| `patch.object(i, m)` | `patch.object(i, m, wraps=i.m)` | #1 Mock-with-Wraps |
| Missing `plt.close()` | Add at test end | #15 Resource Cleanup |
| Default parameter values | Use distinctive values (77, 2.5) | #2 Parameter Passthrough |
2 changes: 1 addition & 1 deletion docs/requirements.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#
# This file is autogenerated by pip-compile with Python 3.12
# This file is autogenerated by pip-compile with Python 3.11
# by the following command:
#
# pip-compile --allow-unsafe --extra=docs --output-file=docs/requirements.txt pyproject.toml
Expand Down
3 changes: 3 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,9 @@ analysis = [
"Bug Tracker" = "https://github.com/blalterman/SolarWindPy/issues"
"Source" = "https://github.com/blalterman/SolarWindPy"

[tool.setuptools.package-data]
solarwindpy = ["core/data/*.csv"]

[tool.pip-tools]
# pip-compile configuration for lockfile generation
generate-hashes = false # Set to true for security-critical deployments
Expand Down
2 changes: 1 addition & 1 deletion requirements-dev.lock
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#
# This file is autogenerated by pip-compile with Python 3.12
# This file is autogenerated by pip-compile with Python 3.11
# by the following command:
#
# pip-compile --allow-unsafe --extra=dev --output-file=requirements-dev.lock pyproject.toml
Expand Down
2 changes: 1 addition & 1 deletion setup.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ tests_require =

[flake8]
extend-select = D402, D413, D205, D406
ignore = E501, W503, D100, D101, D102, D103, D104, D105, D200, D202, D209, D214, D215, D300, D302, D400, D401, D403, D404, D405, D409, D412, D414
ignore = E231, E501, W503, D100, D101, D102, D103, D104, D105, D200, D202, D209, D214, D215, D300, D302, D400, D401, D403, D404, D405, D409, D412, D414
enable = W605
docstring-convention = numpy
max-line-length = 88
Expand Down
65 changes: 0 additions & 65 deletions solarwindpy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,94 +22,29 @@ name: solarwindpy
channels:
- conda-forge
dependencies:
- alabaster
- astropy
- astropy-iers-data
- babel
- black
- python-blosc2
- bottleneck
- certifi
- cfgv
- charset-normalizer
- click
- contourpy
- coverage[toml]
- cycler
- distlib
- doc8
- docstring-inheritance
- docutils
- filelock
- flake8
- flake8-docstrings
- fonttools
- h5py
- identify
- idna
- imagesize
- iniconfig
- jinja2
- kiwisolver
- latexcodec
- llvmlite
- markupsafe
- matplotlib
- mccabe
- msgpack-python
- mypy_extensions
- ndindex
- nodeenv
- numba
- numexpr
- numpy
- numpydoc
- packaging
- pandas
- pathspec
- pillow
- platformdirs
- pluggy
- pre-commit
- psutil
- py-cpuinfo
- pybtex
- pybtex-docutils
- pycodestyle
- pydocstyle
- pyenchant
- pyerfa
- pyflakes
- pygments
- pyparsing
- pytest
- pytest-cov
- python-dateutil
- pytokens
- pytz
- pyyaml
- requests
- restructuredtext_lint
- roman-numerals
- roman-numerals-py
- scipy
- six
- snowballstemmer
- sphinx
- sphinx-rtd-theme
- sphinxcontrib-applehelp
- sphinxcontrib-bibtex
- sphinxcontrib-devhelp
- sphinxcontrib-htmlhelp
- sphinxcontrib-jquery
- sphinxcontrib-jsmath
- sphinxcontrib-qthelp
- sphinxcontrib-serializinghtml
- sphinxcontrib-spelling
- stevedore
- pytables
- tabulate
- typing-extensions
- tzdata
- urllib3
- virtualenv
2 changes: 2 additions & 0 deletions solarwindpy/core/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
from .spacecraft import Spacecraft
from .units_constants import Units, Constants
from .alfvenic_turbulence import AlfvenicTurbulence
from .abundances import ReferenceAbundances

__all__ = [
"Base",
Expand All @@ -20,4 +21,5 @@
"Units",
"Constants",
"AlfvenicTurbulence",
"ReferenceAbundances",
]
103 changes: 103 additions & 0 deletions solarwindpy/core/abundances.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
__all__ = ["ReferenceAbundances"]

import numpy as np
import pandas as pd
from collections import namedtuple
from pathlib import Path

Abundance = namedtuple("Abundance", "measurement,uncertainty")


class ReferenceAbundances:
"""Elemental abundances from Asplund et al. (2009).

Provides both photospheric and meteoritic abundances.

References
----------
Asplund, M., Grevesse, N., Sauval, A. J., & Scott, P. (2009).
The Chemical Composition of the Sun.
Annual Review of Astronomy and Astrophysics, 47(1), 481–522.
https://doi.org/10.1146/annurev.astro.46.060407.145222
"""

def __init__(self):
self.load_data()

@property
def data(self):
r"""Elemental abundances in dex scale:

log ε_X = log(N_X/N_H) + 12

where N_X is the number density of species X.
"""
return self._data

def load_data(self):
"""Load Asplund 2009 data from package CSV."""
path = Path(__file__).parent / "data" / "asplund2009.csv"
data = pd.read_csv(path, skiprows=4, header=[0, 1], index_col=[0, 1]).astype(
np.float64
)
self._data = data

def get_element(self, key, kind="Photosphere"):
r"""Get measurements for element stored at `key`.

Parameters
----------
key : str or int
Element symbol ('Fe') or atomic number (26).
kind : str, default "Photosphere"
Which abundance source: "Photosphere" or "Meteorites".
"""
if isinstance(key, str):
level = "Symbol"
elif isinstance(key, int):
level = "Z"
else:
raise ValueError(f"Unrecognized key type ({type(key)})")

out = self.data.loc[:, kind].xs(key, axis=0, level=level)
assert out.shape[0] == 1
return out.iloc[0]

@staticmethod
def _convert_from_dex(case):
m = case.loc["Ab"]
u = case.loc["Uncert"]
mm = 10.0 ** (m - 12.0)
uu = mm * np.log(10) * u
return mm, uu

def abundance_ratio(self, numerator, denominator):
r"""Calculate abundance ratio N_X/N_Y with uncertainty.

Parameters
----------
numerator, denominator : str or int
Element symbols ('Fe', 'O') or atomic numbers.

Returns
-------
Abundance
namedtuple with (measurement, uncertainty).
"""
top = self.get_element(numerator)
tu = top.Uncert
if np.isnan(tu):
tu = 0

if denominator != "H":
bottom = self.get_element(denominator)
bu = bottom.Uncert
if np.isnan(bu):
bu = 0

rat = 10.0 ** (top.Ab - bottom.Ab)
uncert = rat * np.log(10) * np.sqrt((tu**2) + (bu**2))
else:
rat, uncert = self._convert_from_dex(top)

return Abundance(rat, uncert)
90 changes: 90 additions & 0 deletions solarwindpy/core/data/asplund2009.csv
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
Chemical composition of the Sun from Table 1 in [1].

[1] Asplund, M., Grevesse, N., Sauval, A. J., & Scott, P. (2009). The Chemical Composition of the Sun. Annual Review of Astronomy and Astrophysics, 47(1), 481–522. https://doi.org/10.1146/annurev.astro.46.060407.145222

Kind,,Meteorites,Meteorites,Photosphere,Photosphere
,,Ab,Uncert,Ab,Uncert
Z,Symbol,,,,
1,H,8.22 , 0.04,12.00,
2,He,1.29,,10.93 , 0.01
3,Li,3.26 , 0.05,1.05 , 0.10
4,Be,1.30 , 0.03,1.38 , 0.09
5,B,2.79 , 0.04,2.70 , 0.20
6,C,7.39 , 0.04,8.43 , 0.05
7,N,6.26 , 0.06,7.83 , 0.05
8,O,8.40 , 0.04,8.69 , 0.05
9,F,4.42 , 0.06,4.56 , 0.30
10,Ne,-1.12,,7.93 , 0.10
11,Na,6.27 , 0.02,6.24 , 0.04
12,Mg,7.53 , 0.01,7.60 , 0.04
13,Al,6.43 , 0.01,6.45 , 0.03
14,Si,7.51 , 0.01,7.51 , 0.03
15,P,5.43 , 0.04,5.41 , 0.03
16,S,7.15 , 0.02,7.12 , 0.03
17,Cl,5.23 , 0.06,5.50 , 0.30
18,Ar,-0.05,,6.40 , 0.13
19,K,5.08 , 0.02,5.03 , 0.09
20,Ca,6.29 , 0.02,6.34 , 0.04
21,Sc,3.05 , 0.02,3.15 , 0.04
22,Ti,4.91 , 0.03,4.95 , 0.05
23,V,3.96 , 0.02,3.93 , 0.08
24,Cr,5.64 , 0.01,5.64 , 0.04
25,Mn,5.48 , 0.01,5.43 , 0.04
26,Fe,7.45 , 0.01,7.50 , 0.04
27,Co,4.87 , 0.01,4.99 , 0.07
28,Ni,6.20 , 0.01,6.22 , 0.04
29,Cu,4.25 , 0.04,4.19 , 0.04
30,Zn,4.63 , 0.04,4.56 , 0.05
31,Ga,3.08 , 0.02,3.04 , 0.09
32,Ge,3.58 , 0.04,3.65 , 0.10
33,As,2.30 , 0.04,,
34,Se,3.34 , 0.03,,
35,Br,2.54 , 0.06,,
36,Kr,-2.27,,3.25 , 0.06
37,Rb,2.36 , 0.03,2.52 , 0.10
38,Sr,2.88 , 0.03,2.87 , 0.07
39,Y,2.17 , 0.04,2.21 , 0.05
40,Zr,2.53 , 0.04,2.58 , 0.04
41,Nb,1.41 , 0.04,1.46 , 0.04
42,Mo,1.94 , 0.04,1.88 , 0.08
44,Ru,1.76 , 0.03,1.75 , 0.08
45,Rh,1.06 , 0.04,0.91 , 0.10
46,Pd,1.65 , 0.02,1.57 , 0.10
47,Ag,1.20 , 0.02,0.94 , 0.10
48,Cd,1.71 , 0.03,,
49,In,0.76 , 0.03,0.80 , 0.20
50,Sn,2.07 , 0.06,2.04 , 0.10
51,Sb,1.01 , 0.06,,
52,Te,2.18 , 0.03,,
53,I,1.55 , 0.08,,
54,Xe,-1.95,,2.24 , 0.06
55,Cs,1.08 , 0.02,,
56,Ba,2.18 , 0.03,2.18 , 0.09
57,La,1.17 , 0.02,1.10 , 0.04
58,Ce,1.58 , 0.02,1.58 , 0.04
59,Pr,0.76 , 0.03,0.72 , 0.04
60,Nd,1.45 , 0.02,1.42 , 0.04
62,Sm,0.94 , 0.02,0.96 , 0.04
63,Eu,0.51 , 0.02,0.52 , 0.04
64,Gd,1.05 , 0.02,1.07 , 0.04
65,Tb,0.32 , 0.03,0.30 , 0.10
66,Dy,1.13 , 0.02,1.10 , 0.04
67,Ho,0.47 , 0.03,0.48 , 0.11
68,Er,0.92 , 0.02,0.92 , 0.05
69,Tm,0.12 , 0.03,0.10 , 0.04
70,Yb,0.92 , 0.02,0.84 , 0.11
71,Lu,0.09 , 0.02,0.10 , 0.09
72,Hf,0.71 , 0.02,0.85 , 0.04
73,Ta,-0.12 , 0.04,,
74,W,0.65 , 0.04,0.85 , 0.12
75,Re,0.26 , 0.04,,
76,Os,1.35 , 0.03,1.40 , 0.08
77,Ir,1.32 , 0.02,1.38 , 0.07
78,Pt,1.62 , 0.03,,
79,Au,0.80 , 0.04,0.92 , 0.10
80,Hg,1.17 , 0.08,,
81,Tl,0.77 , 0.03,0.90 , 0.20
82,Pb,2.04 , 0.03,1.75 , 0.10
83,Bi,0.65 , 0.04,,
90,Th,0.06 , 0.03,0.02 , 0.10
92,U,-0.54 , 0.03,,
Loading