neidspec
neidspec provides a spectrum class and supporting utilities for reduced
NEID Level 2 spectra. It is the low-level spectrum dependency used by
NEIDSpecMatch.
Installation
Use Python 3.10, 3.11, or 3.12:
python -m pip install neidspec
Version 0.2 uses a tested pure-NumPy cross-correlation implementation. The
legacy crosscorr package and its Fortran/numpy.distutils build are no
longer required.
Validation boundary
Version 0.2 validates the NEID Level 2 reader, DRP metadata/DQ handling, order mapping, deblazing, resampling, dynamic rotational broadening, and the numerical structure of explicit custom-mask CCF fits. These checks do not by themselves validate a stellar-parameter scale, a particular line mask, or compatibility between different DRP reductions. Publication-facing parameter inference must add a matched reference-library validation product, as NEIDSpecMatch does in its strict mode.
Historical general-purpose modules such as spec_help, stats_help, priors,
and plotting helpers remain importable for compatibility but are outside this
release's publication-validation boundary. The unrelated HPF-only
CreateTemplate helper was removed and must not be used to construct a
NEIDSpecMatch reference library.
Reading a spectrum
from neidspec import NEIDSpectrum
with NEIDSpectrum("neidL2_YYYYMMDDThhmmss.fits") as spectrum:
print(spectrum.drp_version, spectrum.bjd, spectrum.berv)
flux, error = spectrum.resample_order(wavelength_grid, order=102)
The default behavior is deliberately tied to the NEID DRP product:
- Inputs must identify themselves as NEID science, Level 2, high-resolution
products (
INSTRUME=NEID,OBSTYPE=Sci,DATALVL=2,OBS-MODE=HR); other or ambiguous products are rejected. DQLEVEL1andDQLEVEL2are interpreted using the DRP-defined low two assessment bits. Pass (0) is accepted; warning (1) is accepted with a Python warning and marked unvalidated; fail (2) and reserved/invalid (3) are rejected. Missing flags in older products are warned and unvalidated. Userequire_dq_pass=Trueto reject warning or missing assessments. Higher diagnostic bits are preserved and do not by themselves fail an exposure.- BJD_TDB and barycentric velocity are read from per-order
SSBJDnnnandSSBRVnnnheader values. They are not recomputed. - Science and sky flux are deblazed with the corresponding Level 2
SCIBLAZEandSKYBLAZEHDUs. Variance is propagated through the same division. - The stellar rest-frame shift uses the Level 2 weighted
CCFRVMODvalue only after checking that it is finite, interior to the stored CCF grid, and consistent withCCFRVSUM. This is structural validation, not proof that the DRP RV is astrophysically correct. A failed check raises an actionable error; it never silently substitutes a generic-mask CCF. - Reading a spectrum performs no TIC/SIMBAD query and writes no target cache.
- Default unit telluric/sky error factors do not read external line masks. Non-unit mask inflation requires an explicit user-supplied mask path; legacy masks with unresolved redistribution rights are not included in artifacts. Where telluric and sky masks overlap, the larger factor is applied once (a union), rather than multiplying the two factors.
spectrum.drp_version,data_level,observing_mode,observatory, andprovenanceretain reduction metadata for downstream products.
An old external instrument-response file can still be used for controlled comparisons, but it is never selected implicitly:
spectrum = NEIDSpectrum(
filename,
blaze_source="legacy_response",
legacy_response_path="/path/to/response.fits",
)
Optional error inflation around a reviewed external mask is explicit as well:
spectrum = NEIDSpectrum(
filename,
tell_err_factor=2.0,
telluric_mask_path="/path/to/telluric-mask.txt",
)
An explicitly supplied RV takes precedence over the DRP value:
spectrum = NEIDSpectrum(filename, rv=-12.345)
For a custom binary-mask measurement, both the intent and mask must be
explicit (rv_source="custom_ccf", ccf_mask_path=...). The bundled M3 mask
is available for reproducibility tests, but no science-facing method selects
it automatically. In a real GJ 649 v1.3 spectrum test, that generic mask/order
combination selected an approximately 87.9 km/s alias instead of the roughly
4 km/s DRP/library velocity; it is not validated as a general NEID science
mask. Direct calculate_ccf_for_orders and rvabs_for_orders calls therefore
require an explicit mask_path or mask object. Custom-mask fits use bounded
parameters, reject edge/degenerate fits and inconsistent order RVs, and record
the mask SHA-256 plus per-order diagnostics. These numerical checks do not
validate whether the mask is astrophysically appropriate for the target.
NEIDSpecList accepts either a scalar RV or one value per input file. Use
None for files that should use their validated DRP RV, and a catalog value
for spectra whose DRP CCF diagnostics fail:
with NEIDSpecList(filelist=files, rv=[None, -0.7434, None]) as spectra:
...
Lists created from filelist own and close their spectra. A caller-supplied
splist is borrowed and is not closed unless take_ownership=True is explicit.
NEIDSpecList.resample_order(..., order=102) uses the same absolute DRP
array-row order convention as NEIDSpectrum.resample_order and forwards
resampling options such as return_mask and max_gap_factor to every member.
Resampling and rotational broadening
resample_order propagates diagonal variance with squared linear-interpolation
weights and never interpolates across a bad pixel, non-finite wavelength, or a
gap larger than max_gap_factor times the typical source spacing. Unsupported
output pixels are NaN; request the mask with return_mask=True. Interpolation
makes neighboring outputs correlated, especially on an oversampled grid. The
covariance is not returned, and this limitation plus the oversampling ratio are
recorded in spectrum.last_resample_provenance.
Rotational broadening uses a dynamically sized, complete kernel on a uniform
log-wavelength grid. vsini=0 is an exact identity. A half-kernel at every
order edge or masked gap is trimmed to NaN so edge lines are never reflected or
extrapolated into a fit. Optimizers must freeze a common pixel set at their
maximum allowed rotation using
neidspec.rotbroad_help.broadening_valid_mask; otherwise the valid-pixel count
would change with trial vsini. broaden_variance applies squared weights at
each stage as a diagonal approximation; intermediate covariance is omitted and
the result must not be treated as an independent-pixel likelihood.
Order identifiers
NEID arrays contain 122 rows. Array row 0 corresponds to physical echelle order 173, and row 121 corresponds to echelle order 52. NEIDSpecMatch's familiar orders 55 and 102 are array-row indices, not echelle numbers.
from neidspec import order_index_to_echelle
assert order_index_to_echelle(55) == 118
OrderMap is used throughout the package to translate requested DRP row
indices into sliced in-memory arrays and to construct order-specific header
keywords. Out-of-range requests raise an explicit error.
Reproducibility guidance
Record spectrum.drp_version with derived results. Do not combine spectra or
reference libraries reduced with different NEID DRP minor versions without a
specific validation. neidspec records the version; it does not silently
declare mixed reductions scientifically equivalent.
Optional target resolution
NEIDSpectrum(..., resolve_target=True) retains the legacy catalog-resolution
convenience and may query remote services. It is not needed for NEID
barycentric metadata. Generic barycentric recomputation through Target
requires an observatory to be supplied explicitly. Named aliases are restricted
to NEID, KPNO, WIYN, and WIYN 3.5m, using coordinates recorded in NEID
Level 2 headers; other sites must provide latitude, longitude, and elevation
explicitly, and unknown names raise instead of falling back to geocentric
coordinates. No McDonald Observatory or APO default remains. Catalog RVs
retained by Target in km/s are converted to the m/s units required by
barycorrpy.
Tests
The regression suite uses only synthetic FITS fixtures:
python -m unittest discover -s tests -v
Third-party algorithm attribution is recorded in
THIRD_PARTY_NOTICES.md.
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file neidspec-0.2.0.tar.gz.
File metadata
- Download URL: neidspec-0.2.0.tar.gz
- Upload date:
- Size: 327.0 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
a59f105166209891b03fe011e17a7ae8c246226fba01c19e21eff3ba6fedc928
|
|
| MD5 |
9f7ffe52d6726a66986fbc88727cb1c4
|
|
| BLAKE2b-256 |
780847733599ddc7e243a52d7afc0684375d1d0a2474cd0fcc0bc73f98ca1c24
|
Provenance
The following attestation bundles were made for neidspec-0.2.0.tar.gz:
Publisher:
release.yml on TeHanHunter/neidspec
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
neidspec-0.2.0.tar.gz -
Subject digest:
a59f105166209891b03fe011e17a7ae8c246226fba01c19e21eff3ba6fedc928 - Sigstore transparency entry: 2667245523
- Sigstore integration time:
-
Permalink:
TeHanHunter/neidspec@f46258595e77b38fcb9e119f0451a618d98216f1 -
Branch / Tag:
refs/tags/v0.2.0 - Owner: https://github.com/TeHanHunter
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@f46258595e77b38fcb9e119f0451a618d98216f1 -
Trigger Event:
push
-
Statement type:
File details
Details for the file neidspec-0.2.0-py3-none-any.whl.
File metadata
- Download URL: neidspec-0.2.0-py3-none-any.whl
- Upload date:
- Size: 154.7 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
7fcbd8fb3c151121777863c62c51d7cdb8d0bb1abdf62be32ec907f1e4ed7768
|
|
| MD5 |
a33c42435f0d722676566eeda8486f1e
|
|
| BLAKE2b-256 |
106930bfd720a45be5114900c5fc115245774e58d9e441a865d2ffbaf7376b88
|
Provenance
The following attestation bundles were made for neidspec-0.2.0-py3-none-any.whl:
Publisher:
release.yml on TeHanHunter/neidspec
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
neidspec-0.2.0-py3-none-any.whl -
Subject digest:
7fcbd8fb3c151121777863c62c51d7cdb8d0bb1abdf62be32ec907f1e4ed7768 - Sigstore transparency entry: 2667245569
- Sigstore integration time:
-
Permalink:
TeHanHunter/neidspec@f46258595e77b38fcb9e119f0451a618d98216f1 -
Branch / Tag:
refs/tags/v0.2.0 - Owner: https://github.com/TeHanHunter
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@f46258595e77b38fcb9e119f0451a618d98216f1 -
Trigger Event:
push
-
Statement type: