Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
70 commits
Select commit Hold shift + click to select a range
80e3b97
updating the desired method for making PRs
nielsenmb Oct 8, 2024
8759b0c
started making tests
nielsenmb Oct 8, 2024
76a0c06
moved samplers to a their own module
nielsenmb Oct 14, 2024
ae1f544
moved samplers to their own module
nielsenmb Oct 14, 2024
b6b60b7
kwargs fix to integrate into star
nielsenmb Oct 14, 2024
b498a79
rename for consistency
nielsenmb Oct 14, 2024
c3174d0
initial working version of star
nielsenmb Oct 15, 2024
c9ced05
simplified IO since LK is much faster these days
nielsenmb Oct 16, 2024
848110a
naming fix for consistency
nielsenmb Oct 16, 2024
b2e1681
renaming for consistency
nielsenmb Oct 16, 2024
15a64e7
bringing IO and session up to date
nielsenmb Oct 21, 2024
d7f5b75
adding doppler velocity correction
nielsenmb Oct 29, 2024
5a3175c
fix for lnlike test in initSamples
nielsenmb Oct 29, 2024
7c8c751
RVs can now be input into star
nielsenmb Oct 29, 2024
5ee93ff
adding speed of light to constants
nielsenmb Oct 29, 2024
ff3cc5e
Update to the star class tutorial.
nielsenmb Oct 29, 2024
4c9dd69
adding kstest to peakbag results
nielsenmb Oct 29, 2024
be0f068
fix issue with slanted echelles
nielsenmb Oct 29, 2024
56dd734
fix for slanted echelles due to echelle sampling argument
nielsenmb Oct 31, 2024
da23951
added arg to modeID call to specify model
nielsenmb Dec 6, 2024
e7ca7e0
adding automatic model selection to l=1 model
nielsenmb Jan 16, 2025
f2304f5
updating main dir for pypi upload
nielsenmb Jan 17, 2025
01054ec
more cleanup
nielsenmb Jan 17, 2025
d020816
cleaning up examples
nielsenmb Jan 17, 2025
4e609ba
adding some chaos
nielsenmb Jan 17, 2025
4d6aed6
updating docs
nielsenmb Jan 20, 2025
46bf583
fix some paths to examples
nielsenmb Jan 20, 2025
fef5297
adding tqdm
nielsenmb Jan 20, 2025
25209b5
not used??
nielsenmb Jan 20, 2025
5bf78c1
Improved echelle and spectrums plots
George-Hookway Jan 30, 2025
cfe53f1
Improvements to selection of radial orders to be fitted, and the such
George-Hookway Feb 6, 2025
53f69da
Improved echelle plots
George-Hookway Feb 6, 2025
b5985a4
Merge branch 'master' of github.com:grd349/PBjam into dev
nielsenmb Feb 17, 2025
01dc4e3
fix for the readthedocs yaml file
nielsenmb Feb 24, 2025
1f12bf4
Update readthedocs.yaml
nielsenmb Feb 24, 2025
778a5f4
Merge pull request #287 from grd349/nielsenmb-patch-2
nielsenmb Feb 24, 2025
26ec022
Merge branch 'master' of github.com:grd349/PBjam into dev
nielsenmb Feb 24, 2025
66b01dd
Merge branch 'master' of github.com:grd349/PBjam into dev
nielsenmb Feb 24, 2025
688be35
Merge branch 'dev' of https://github.com/grd349/PBjam into George
George-Hookway Feb 24, 2025
e170ff7
should use correct commenting style
nielsenmb Feb 26, 2025
5a30c58
default values should not be set here
nielsenmb Feb 26, 2025
9bf1766
Merge pull request #283 from grd349/George
nielsenmb Feb 26, 2025
c3ce650
increased modewidth
nielsenmb Feb 28, 2025
9a71384
cleanup GP commented out bits in case of experimentation
nielsenmb Feb 28, 2025
4114fa5
adding a wrapper for making dist objects from the kde of a dataset
nielsenmb Feb 28, 2025
ed2b1e1
adding validation module
nielsenmb Feb 28, 2025
48ca943
adding dipole masking
nielsenmb Mar 17, 2025
9b0c9cd
updating a few things for pypi update
nielsenmb Mar 20, 2025
8415920
Quick pass with typos CLI tool
warrickball Mar 20, 2025
6400676
one more typo
warrickball Mar 20, 2025
f644fad
Merge pull request #290 from warrickball/typos
nielsenmb Mar 21, 2025
346ca07
fix for readthedocs.yaml to work with pyprojects.toml
nielsenmb Jun 24, 2025
256d118
fix for validation module
nielsenmb Jun 24, 2025
04d3707
Merge branch 'dev' of github.com:grd349/PBjam into dev
nielsenmb Jun 24, 2025
8daa101
fix for readthedocs config
nielsenmb Jun 24, 2025
cba3279
safety patch for extremely binned time series
nielsenmb Jul 21, 2025
1dacae5
updating prior with Hookway2025
nielsenmb Nov 6, 2025
a737b00
Added prior selection trick for speed
May 11, 2026
7eef093
Testing normal dist and prior refienment
May 12, 2026
7e4b0b3
New prior behaviour
May 12, 2026
0a1a2f1
Set emcee likelihood multiplier to one
May 12, 2026
363f393
Fix core validation and add coverage
May 12, 2026
8c27f48
Improve modeID documentation
May 12, 2026
f9804f9
Refine prior retries and modeID constraints
May 12, 2026
0e77025
Various small changes
May 14, 2026
d951fa6
Add combined main sequence mode ID model
May 14, 2026
cdff40a
Route prior kwargs through mode ID calls
May 14, 2026
fa9b412
Updated prior file from George
May 15, 2026
4713a68
Merge remote-tracking branch 'origin/dev' into prior-selection-dev
May 19, 2026
42655f1
Update tutorial docs wiring
May 19, 2026
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
1 change: 1 addition & 0 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ PBjam is toolbox for analyzing the oscillation spectra of solar-like oscillators

The mode identification works by fitting the asymptotic relation for p-modes to the l=2,0 pairs, which is followed by a applying selection of models for fitting the l=1 modes where each model is suitable for different stages of evolution.
The process relies on of large set of previous observations of the model parameters, which are then used to construct a prior distribution to inform the sampling. The observations have been gathered from the Kepler, K2 and TESS missions, and expanding it to improve accuracy is an on-going process.
The ``runl20model`` and ``runl1model`` mode-identification calls accept a ``loglikelihoodMultiplier`` argument, defaulting to ``1.0``, which scales the final log-likelihood value passed to the nested sampler.

Modeling the modes, or 'peakbagging', is done using the a nested sampling or MCMC algorithm, where Lorentzian profiles are fit to each of the identified modes, with much fewer constraints than during the mode ID process. This allows for a more accurate model of the spectrum of frequencies than the heavily parameterized models like the asymptotic relations.

Expand Down
4 changes: 4 additions & 0 deletions docs/source/MSmodels.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
MSmodels
^^^^^^^^
.. automodule:: pbjam.MSmodels
:members:
2 changes: 1 addition & 1 deletion docs/source/api.rst
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ Modules in PBjam
jar
l1models
l20models
MSmodels
modeID
peakbagging
plotting
Expand All @@ -31,4 +32,3 @@ Modules in PBjam




33 changes: 17 additions & 16 deletions docs/source/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,12 @@
import os
import sys
sys.path.insert(0, os.path.abspath('../..'))
from importlib.metadata import PackageNotFoundError, version as package_version

try:
pbjam_version = package_version('pbjam')
except PackageNotFoundError:
pbjam_version = '0+unknown'


# -- Project information -----------------------------------------------------
Expand All @@ -24,9 +30,9 @@
author = 'Martin Nielsen'

# The short X.Y version
version = ''
version = '.'.join(pbjam_version.split('.')[:2])
# The full version, including alpha/beta/rc tags
release = '0.0.1'
release = pbjam_version


# -- General configuration ---------------------------------------------------
Expand All @@ -52,12 +58,11 @@
'nbsphinx',
]



# If your notebooks contain non-trivial outputs like images, set this option
nbsphinx_allow_errors = True # This ensures Sphinx builds even if a notebook fails
# Keep notebook conversion failures visible during docs builds.
nbsphinx_allow_errors = False

# Run the notebooks or never.
# Tutorials download mission data and run expensive samplers, so docs builds
# render the checked-in outputs instead of re-executing notebooks.
nbsphinx_execute = 'never'

# Exclude build directory and Jupyter backup files:
Expand All @@ -69,9 +74,10 @@
# The suffix(es) of source filenames.
# You can specify multiple suffix as a list of string:
#
# source_suffix = ['.rst', '.md']
#source_suffix = '.rst'
source_suffix = {'.rst': 'restructuredtext'}
source_suffix = {
'.rst': 'restructuredtext',
'.ipynb': 'nbsphinx',
}

# The master toctree document.
master_doc = 'index'
Expand All @@ -83,11 +89,6 @@
# Usually you set "language" from the command line for these cases.
language = 'en'

# List of patterns, relative to source directory, that match files and
# directories to ignore when looking for source files.
# This pattern also affects html_static_path and html_extra_path.
exclude_patterns = []

# The name of the Pygments (syntax highlighting) style to use.
pygments_style = None

Expand Down Expand Up @@ -208,4 +209,4 @@
# If true, `todo` and `todoList` produce output, else they produce nothing.
todo_include_todos = True

autodoc_default_flags = ['members', 'special-members']
autodoc_default_flags = ['members', 'special-members']
16 changes: 16 additions & 0 deletions docs/source/examples.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
Examples
========

These notebooks demonstrate the main PBjam workflows.

.. toctree::
:maxdepth: 1

Examples/example-session.ipynb
Examples/example-star.ipynb
Examples/example-modeID.ipynb
Examples/example-peakbag.ipynb
Examples/example-plotting.ipynb
Examples/example-docstrings
Examples/example-unittests
Examples/example-githubworkflow
1 change: 1 addition & 0 deletions docs/source/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

setup
usage
examples
api
license
help
Expand Down
6 changes: 3 additions & 3 deletions docs/source/usage.rst
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ PBjam is intended to be a user-friendly peakbagging tool. The most straightforwa

Session
-------
The :class:`~pbjam.core.session` class is the most straightforward way to analyze one or more stars with PBjam. It can automatically download the data and compute the power density spectrum, and then go through all the steps in the moden ID and peakbagging process. The `Session notebook <Examples/example-session.ipynb>`_ provides an example of how to use the :class:`~pbjam.core.session` class.
The :class:`~pbjam.core.session` class is the most straightforward way to analyze one or more stars with PBjam. It can automatically download the data and compute the power density spectrum, and then go through all the steps in the mode ID and peakbagging process. The `Session notebook <Examples/example-session.ipynb>`_ provides an example of how to use the :class:`~pbjam.core.session` class.


Star
Expand All @@ -20,8 +20,8 @@ Advanced
It is not strictly necessary to use either the :class:`~pbjam.core.session` or :class:`~pbjam.core.star` classes. The `mode ID <Examples/example-modeID.ipynb>`_ and `peakbag <Examples/example-peakbag.ipynb>`_ notebooks show a lower-level walkthrough of the steps that PBjam goes through for peakbagging.

.. note::
For additional useful examples see the `Examples <https://github.com/grd349/PBjam/tree/master/Examples>`_ directory.
For additional useful examples see the `Examples <examples.html>`_ page.

Papers
------
We have published a few papers on various bits. The `first paper <https://ui.adsabs.harvard.edu/abs/2021AJ....161...62N/abstract>`_ provides information mainly on the initial version of PBjam. The `second paper <https://ui.adsabs.harvard.edu/abs/2023A%26A...676A.117N/abstract>`_ discusses the method used to construct the prior probability densities that we now use in the latest version of PBjam. The latest paper (in prep.) focuses on how we construct the models for the l=1 modes.
We have published a few papers on various bits. The `first paper <https://ui.adsabs.harvard.edu/abs/2021AJ....161...62N/abstract>`_ provides information mainly on the initial version of PBjam. The `second paper <https://ui.adsabs.harvard.edu/abs/2023A%26A...676A.117N/abstract>`_ discusses the method used to construct the prior probability densities that we now use in the latest version of PBjam. The latest paper (in prep.) focuses on how we construct the models for the l=1 modes.
111 changes: 110 additions & 1 deletion pbjam/DR.py
Original file line number Diff line number Diff line change
Expand Up @@ -309,7 +309,7 @@ def fit_weightedPCA(self, dim):

self.covariance = self.covarianceMatrix(_X)

self.eigvals, self.eigvectors = jnp.linalg.eig(self.covariance)
self.eigvals, self.eigvectors = jnp.linalg.eigh(self.covariance)

self.sortidx = sorted(range(len(self.eigvals)), key=lambda i: self.eigvals[i], reverse=True)[:self.dimsR]

Expand All @@ -319,6 +319,29 @@ def fit_weightedPCA(self, dim):

self.dataR = self.transform(self.dataF)

def setLatentNormalPrior(self, latentSample=None):
"""Set independent normal priors for each latent PCA coordinate."""

from pbjam import distributions as dist

if latentSample is None:
latentSample = self.dataR

latentSample = np.asarray(latentSample)
loc = np.mean(latentSample, axis=0)
scale = np.std(latentSample, axis=0)
scale = np.where(np.isfinite(scale) & (scale > 0), scale, 1.0)

self.latentPriorLoc = jnp.array(loc)
self.latentPriorScale = jnp.array(scale)
self.latentPriors = [dist.normal(loc=self.latentPriorLoc[i],
scale=self.latentPriorScale[i])
for i in range(self.dimsR)]
self.ppf = [prior.ppf for prior in self.latentPriors]
self.pdf = [prior.pdf for prior in self.latentPriors]
self.logpdf = [prior.logpdf for prior in self.latentPriors]
self.cdf = [prior.cdf for prior in self.latentPriors]

def covarianceMatrix(self, _X):
""" Compute the weighted covariance matrix

Expand All @@ -338,3 +361,89 @@ def covarianceMatrix(self, _X):
C = _X.T@W@_X * jnp.sum(self.weights) / (jnp.sum(self.weights)**2 - jnp.sum(self.weights**2))

return C

def refinePriorByObservables(self, N=10000, minAccepted=100, sigmaInflation=1,
rng=None):
"""Refit latent normal priors using draws consistent with observations.

Draws from the current latent prior, maps those points into the PCA
parameter space, accepts them with a normal likelihood in the observed
dimensions, and rebuilds the independent latent normal priors from the
accepted points.
"""

if not hasattr(self, 'ppf'):
raise AttributeError('Set the initial latent prior before refining the prior.')

if not hasattr(self, 'dimsR') or self.dimsR == 0:
return None

obsLabels = [key for key in self.selectLabels
if (key in self.varLabels) and (key in self.obs)]

obsLabels = [key for key in obsLabels if self.obs[key][1] > 0]

if len(obsLabels) == 0:
warnings.warn('Selective prior refinement skipped: no observed selection labels are in the PCA variables.',
stacklevel=2)
return None

if rng is None:
rng = np.random.default_rng()
elif not hasattr(rng, 'uniform'):
rng = np.random.default_rng(rng)

obsIdx = np.array([self.varLabels.index(key) for key in obsLabels])
obsVals = np.array([self.obs[key][0] for key in obsLabels])
baseObsErrs = np.array([self.obs[key][1] for key in obsLabels])

nDraws = max(1, int(N))
currentSigmaInflation = sigmaInflation
while True:
latentDraws = rng.normal(loc=np.asarray(self.latentPriorLoc),
scale=np.asarray(self.latentPriorScale),
size=(nDraws, self.dimsR))

physicalDraws = np.asarray(self.inverse_transform(jnp.array(latentDraws)))

finite = np.all(np.isfinite(physicalDraws), axis=1)
obsErrs = baseObsErrs * currentSigmaInflation
delta = (physicalDraws[:, obsIdx] - obsVals) / obsErrs
logLike = -0.5 * np.sum(delta**2, axis=1)
finite &= np.isfinite(logLike)

if not np.any(finite):
raise ValueError('Selective prior refinement found no finite prior draws.')

acceptProb = np.zeros_like(logLike)
acceptProb[finite] = np.exp(logLike[finite] - np.max(logLike[finite]))
accepted = rng.uniform(0, 1, size=len(logLike)) < acceptProb

M = int(np.sum(accepted))
self.selectivePriorInfo = {'draws': nDraws,
'accepted': M,
'minAccepted': int(minAccepted),
'sigmaInflation': currentSigmaInflation,
'labels': obsLabels}

if M >= minAccepted:
break

nextNDraws = 2 * nDraws
nextSigmaInflation = 2 * currentSigmaInflation
warnings.warn(f'Selective prior refinement accepted {M} points, fewer than minAccepted={minAccepted}. '
f'Retrying with {nextNDraws} draws and sigmaInflation={nextSigmaInflation}.',
stacklevel=2)
nDraws = nextNDraws
currentSigmaInflation = nextSigmaInflation

self.selectivePhysicalSample = physicalDraws[accepted, :]
self.selectiveSubset = pd.DataFrame(self.selectivePhysicalSample, columns=self.varLabels)

selectiveLatentSample = np.asarray(self.transform(jnp.array(self.selectivePhysicalSample)))
self.selectiveLatentSample = selectiveLatentSample

self.dataR = jnp.array(selectiveLatentSample)
self.setLatentNormalPrior(selectiveLatentSample)

return selectiveLatentSample
4 changes: 2 additions & 2 deletions pbjam/IO.py
Original file line number Diff line number Diff line change
Expand Up @@ -301,7 +301,8 @@ def windowfunction(self, df, width=None, oversampling=10):
if width is None:
width = 100*df

freq_cen = 0.5*self.Nyquist
# freq_cen = 0.5*self.Nyquist
freq_cen = max([0.5*self.Nyquist, width + df])

Nfreq = int(oversampling*width/df)

Expand Down Expand Up @@ -554,4 +555,3 @@ def _getPriorPath():

return os.path.join(*[PACKAGEDIR, 'data', 'prior_data.csv'])


Loading