Skip to content
This repository was archived by the owner on May 11, 2026. It is now read-only.
Merged

Dev #57

Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
e304e39
bug: fixed edge case in infer_gtis() function that could cause issues…
zairving Oct 6, 2025
1fe6eab
misc: fixed missing axis label in catalog plot and improved resolutio…
zairving Oct 6, 2025
17580d8
feat: added some additional customisation parameters to phase_bin_lig…
zairving Oct 6, 2025
faa8998
feat: added overwriting saveguard to photometry() method of Reducer a…
zairving Oct 6, 2025
694223b
misc: renamed "match_sources" atrribute of photometers to "forced" fo…
zairving Oct 6, 2025
bf125d3
misc: when aligning images using transform_type="translation", alignm…
zairving Oct 6, 2025
9805b5a
docs: updated README
zairving Oct 6, 2025
27ebd86
bug: fixed issue in log_binnings() and log_filters() functions where …
zairving Oct 9, 2025
cf9d69b
feat: made barycentric corrects optional for backwards compatibility
zairving Oct 9, 2025
02a1c49
misc: renamed SimplePhotometer to the more apt AperturePhotometer and…
zairving Oct 9, 2025
d3f9e11
misc: changed SimplePhotometer to the more apt AperturePhotometer
zairving Oct 9, 2025
a2c85b5
docs: updated reduction tutorial to use new AperturePhotometry class
zairving Oct 9, 2025
d53d6d9
misc: added dt/2 padding to the GTIs inferred by infer_gtis()
zairving Oct 13, 2025
70ee115
misc: log_binnings() and log_filters() will now create the required o…
zairving Oct 20, 2025
40111cf
docs: clarified docstring for save_stacked_images
zairving Oct 20, 2025
76daeb3
feat: added routine for plotting growth curves and changed image colo…
zairving Oct 20, 2025
2e0e654
misc: master flats are now stored in a compressed FITS cube instead o…
zairving Oct 20, 2025
4d6c812
misc: made errorbars in plot_light_curves() translucent
zairving Oct 20, 2025
8cf7bf6
feat: added plot_growth_curves() method to Reducer for creating growt…
zairving Oct 20, 2025
094d70d
feat: added routine for creating growth curves and added option to se…
zairving Oct 20, 2025
c19d3a3
misc: improved presentation of some plots
zairving Oct 21, 2025
a6d5dbe
feat: improved PSF visualisation, added fittable models subpackage, a…
zairving Oct 21, 2025
a4a3482
feat: updated photometry to only be performed on aligned images
zairving Oct 22, 2025
13a58e8
misc: increased BaseLocalBackground default outer annulus radius
zairving Oct 22, 2025
34729e0
misc: increased border for source positioning in data generation scri…
zairving Oct 23, 2025
41f2d41
misc: removed gain parameter from get_data() and made sure get_time()…
zairving Oct 23, 2025
3d73206
misc: raw light curves are now saved to dedicated subdirectories with…
zairving Oct 23, 2025
a96be8f
feat: GTIs are now shown when calling the plot_light_curves() method …
zairving Oct 23, 2025
939e702
misc: increased source_matching_tolerance from 2 sigma to 5 sigma for…
zairving Oct 23, 2025
74c3e69
feat: made GTI visualisation in Analyzer.plot_light_curves() optional…
zairving Oct 24, 2025
1e44bed
docs: updated tutorials
zairving Oct 24, 2025
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
2 changes: 1 addition & 1 deletion docs/README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Documentation

To generate the Sphinx documentation for `opticam_new`, install the package with its documentation requirements:
To generate the Sphinx documentation for `opticam`, install the package with its documentation requirements:

```
pip install -e .[docs]
Expand Down
189 changes: 116 additions & 73 deletions docs/tutorials/applying_corrections.ipynb

Large diffs are not rendered by default.

143 changes: 101 additions & 42 deletions docs/tutorials/backgrounds.ipynb

Large diffs are not rendered by default.

212 changes: 116 additions & 96 deletions docs/tutorials/finders.ipynb

Large diffs are not rendered by default.

332 changes: 163 additions & 169 deletions docs/tutorials/local_backgrounds.ipynb

Large diffs are not rendered by default.

101 changes: 41 additions & 60 deletions docs/tutorials/reduction.ipynb

Large diffs are not rendered by default.

818 changes: 665 additions & 153 deletions docs/tutorials/timing_methods.ipynb

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion opticam/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
from opticam.finders import DefaultFinder
from opticam.reducer import Reducer
from opticam.analysis.differential_photometer import DifferentialPhotometer
from opticam.photometers import SimplePhotometer, OptimalPhotometer
from opticam.photometers import AperturePhotometer, OptimalPhotometer
from opticam.correctors.flat_field_corrector import FlatFieldCorrector
from opticam.analysis.analyzer import Analyzer
from opticam.utils.generate import generate_flats, generate_observations, generate_gappy_observations
Expand Down
5 changes: 2 additions & 3 deletions opticam/align.py
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,6 @@ def align_batch(
data = np.asarray(
get_data(
file,
gains[file],
flat_corrector=flat_corrector,
rebin_factor=rebin_factor,
return_error=False,
Expand All @@ -125,8 +124,8 @@ def align_batch(
logger.info(f'[OPTICAM] No sources detected in {file}: {e}.')
continue

if len(coords) < len(reference_coords):
logger.info(f'[OPTICAM] n_alignment_sources={len(reference_coords)} but only {len(coords)} sources detected in {file}. Skipping.')
if len(coords) < n_alignment_sources and transform_type == 'translation':
logger.info(f'[OPTICAM] {len(coords)} sources detected in {file} but n_alignment_sources={n_alignment_sources} and transform_type="translation". Skipping. To attempt to align images in which fewer than n_alignment_sources are detected, try transform_type="affine".')
continue

if transform_type == 'translation':
Expand Down
150 changes: 99 additions & 51 deletions opticam/analysis/analyzer.py
Original file line number Diff line number Diff line change
Expand Up @@ -140,15 +140,15 @@ def rebin_light_curves(

def plot_light_curves(
self,
title: str | None = None,
show_gtis: bool = False,
) -> Figure:
"""
Plot the light curves.

Parameters
----------
title : str | None, optional
The figure title, by default `None`.
show_gtis : bool, optional
Whether to highlight the Good Time Intervals on the light curve plot, by default `False`.

Returns
-------
Expand All @@ -170,9 +170,7 @@ def plot_light_curves(
axes = [axes]

for i, (fltr, lc) in enumerate(self.light_curves.items()):

for lc_segment in lc.split_by_gti(min_points=1):

t = (np.asarray(lc_segment.time) - self.t_ref) * 86400

axes[i].errorbar(
Expand All @@ -183,6 +181,7 @@ def plot_light_curves(
linestyle='none',
ecolor='grey',
elinewidth=1,
alpha=.5,
)
axes[i].step(
t,
Expand All @@ -202,12 +201,24 @@ def plot_light_curves(
va='top',
ha='right',
)

if show_gtis:
gti = 86400 * (np.asarray(lc.gti) - self.t_ref)
for j in range(gti.shape[0] - 1):
stop = gti[j][1]
start = gti[j + 1][0]

axes[i].fill_betweenx(
axes[i].set_ylim(),
stop,
start,
color='grey',
edgecolor='none',
alpha=.5,
)

axes[-1].set_xlabel(f'Time from BMJD {self.t_ref:.4f} [s]', fontsize='large')
axes[len(self.light_curves) // 2].set_ylabel('Normalised flux', fontsize='large')

if title is not None:
axes[0].set_title(title)
axes[len(self.light_curves) // 2].set_ylabel('Normalized flux', fontsize='large')

for ax in axes:
ax.minorticks_on()
Expand Down Expand Up @@ -307,7 +318,9 @@ def phase_bin_light_curves(
period: Quantity,
t0: float | None = None,
n_bins: int = 10,
plot=True,
plot: bool = True,
subplot : bool = True,
sharey: bool = False,
) -> Dict[str, Dict[str, NDArray]]:
"""
Phase bin each light curve using the given period.
Expand All @@ -323,6 +336,11 @@ def phase_bin_light_curves(
The number of phase bins, by default 10.
plot : bool, optional
Whether to plot the phase binned light curves, by default True.
subplot : bool, optional
Whether to plot filters in separate subplots, by default True.
sharey : bool, optional
Whether to render the plot with a common y-axis (useful for directly comparing amplitudes), by default
False. Only used if `plot=True` and `subplot=True`.

Returns
-------
Expand Down Expand Up @@ -367,46 +385,77 @@ def phase_bin_light_curves(
}

if plot:
fig, axes = plt.subplots(
tight_layout=True,
nrows=len(self.light_curves),
sharex=True,
figsize=(6.4, (0.5 * len(self.light_curves) * 4.8)),
gridspec_kw={'hspace': 0.},
)

for i, (fltr, lc) in enumerate(self.light_curves.items()):
axes[i].errorbar(
np.append(results[fltr]['phase'], results[fltr]['phase'] + 1),
np.append(results[fltr]['flux'], results[fltr]['flux']),
np.append(results[fltr]['flux error'], results[fltr]['flux error']),
marker='none',
linestyle='none',
color=colors[fltr],
ecolor='grey',
elinewidth=1,
if subplot:
fig, axes = plt.subplots(
tight_layout=True,
nrows=len(self.light_curves),
sharex=True,
sharey=sharey,
figsize=(6.4, (0.5 * len(self.light_curves) * 4.8)),
gridspec_kw={'hspace': 0.},
)
axes[i].step(
np.append(results[fltr]['phase'], results[fltr]['phase'] + 1),
np.append(results[fltr]['flux'], results[fltr]['flux']),
where='mid',
color=colors[fltr],
lw=1,
)
axes[i].text(
.95,
.9,
fltr,
fontsize='large',
va='top',
ha='right',
transform=axes[i].transAxes,
)

axes[-1].set_xlabel('Phase')
axes[len(self.light_curves) // 2].set_ylabel('Normalized flux')

for ax in axes.flatten():

for i, (fltr, lc) in enumerate(self.light_curves.items()):
axes[i].errorbar(
np.append(results[fltr]['phase'], results[fltr]['phase'] + 1),
np.append(results[fltr]['flux'], results[fltr]['flux']),
np.append(results[fltr]['flux error'], results[fltr]['flux error']),
marker='none',
linestyle='none',
color=colors[fltr],
ecolor='grey',
elinewidth=1,
)
axes[i].step(
np.append(results[fltr]['phase'], results[fltr]['phase'] + 1),
np.append(results[fltr]['flux'], results[fltr]['flux']),
where='mid',
color=colors[fltr],
lw=1,
)
axes[i].text(
.95,
.9,
fltr,
fontsize='large',
va='top',
ha='right',
transform=axes[i].transAxes,
)

axes[-1].set_xlabel('Phase', fontsize='large')
axes[len(self.light_curves) // 2].set_ylabel('Normalized flux', fontsize='large')

for ax in axes.flatten():
ax.minorticks_on()
ax.tick_params(which='both', direction='in', top=True, right=True)
else:
fig, ax = plt.subplots(
tight_layout=True,
)

for i, (fltr, lc) in enumerate(self.light_curves.items()):
ax.errorbar(
np.append(results[fltr]['phase'], results[fltr]['phase'] + 1),
np.append(results[fltr]['flux'], results[fltr]['flux']),
np.append(results[fltr]['flux error'], results[fltr]['flux error']),
marker='none',
linestyle='none',
color=colors[fltr],
ecolor='grey',
elinewidth=1,
)
ax.step(
np.append(results[fltr]['phase'], results[fltr]['phase'] + 1),
np.append(results[fltr]['flux'], results[fltr]['flux']),
where='mid',
color=colors[fltr],
label=fltr,
)

ax.set_xlabel('Phase', fontsize='large')
ax.set_ylabel('Normalized flux', fontsize='large')
ax.legend(fontsize='large')
ax.minorticks_on()
ax.tick_params(which='both', direction='in', top=True, right=True)

Expand Down Expand Up @@ -679,14 +728,13 @@ def validate_light_curves(
counts /= mean_flux
counts_err /= mean_flux

# convert DataFrame to Lightcurve
validated_light_curves[fltr] = Lightcurve(
time,
counts,
err=counts_err,
gti=gtis,
err_dist='gauss',
)
).sort()

return sort_filters(validated_light_curves)

Expand Down
Loading
Loading