exosim 2.2.0__tar.gz → 2.2.2__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- exosim-2.2.2/CHANGELOG.rst +288 -0
- {exosim-2.2.0 → exosim-2.2.2}/CITATION.cff +2 -2
- {exosim-2.2.0 → exosim-2.2.2}/PKG-INFO +12 -10
- {exosim-2.2.0 → exosim-2.2.2}/README.md +10 -0
- {exosim-2.2.0 → exosim-2.2.2}/RELEASING.md +6 -6
- {exosim-2.2.0 → exosim-2.2.2}/codemeta.json +2 -2
- {exosim-2.2.0 → exosim-2.2.2}/pyproject.toml +5 -9
- exosim-2.2.2/scripts/changelog_extract.py +74 -0
- {exosim-2.2.0 → exosim-2.2.2}/scripts/release.py +40 -11
- {exosim-2.2.0 → exosim-2.2.2}/src/exosim/__about__.py +4 -1
- {exosim-2.2.0 → exosim-2.2.2}/src/exosim/models/channel.py +8 -2
- {exosim-2.2.0 → exosim-2.2.2}/src/exosim/models/signal.py +5 -5
- {exosim-2.2.0 → exosim-2.2.2}/src/exosim/plots/focal_plane_plotter.py +1 -1
- {exosim-2.2.0 → exosim-2.2.2}/src/exosim/recipes/create_focal_plane.py +19 -11
- {exosim-2.2.0 → exosim-2.2.2}/src/exosim/recipes/radiometric_model.py +11 -5
- {exosim-2.2.0 → exosim-2.2.2}/src/exosim/tasks/astrosignal/estimate_planetary_signal.py +4 -1
- {exosim-2.2.0 → exosim-2.2.2}/src/exosim/tasks/detector/accumulate_sub_exposures.py +7 -3
- {exosim-2.2.0 → exosim-2.2.2}/src/exosim/tasks/detector/add_cosmic_rays.py +1 -0
- {exosim-2.2.0 → exosim-2.2.2}/src/exosim/tasks/detector/add_gain_drift.py +5 -0
- {exosim-2.2.0 → exosim-2.2.2}/src/exosim/tasks/detector/analog_to_digital.py +4 -2
- {exosim-2.2.0 → exosim-2.2.2}/src/exosim/tasks/detector/apply_pixels_non_linearity.py +3 -1
- {exosim-2.2.0 → exosim-2.2.2}/src/exosim/tasks/detector/merge_groups.py +11 -0
- {exosim-2.2.0 → exosim-2.2.2}/src/exosim/tasks/foregrounds/estimate_zodi.py +2 -2
- {exosim-2.2.0 → exosim-2.2.2}/src/exosim/tasks/instrument/compute_sources_pointing_offset.py +33 -10
- {exosim-2.2.0 → exosim-2.2.2}/src/exosim/tasks/instrument/create_focal_plane_array.py +5 -11
- {exosim-2.2.0 → exosim-2.2.2}/src/exosim/tasks/radiometric/compute_constant_dark_current_noise.py +5 -5
- {exosim-2.2.0 → exosim-2.2.2}/src/exosim/tasks/radiometric/compute_constant_read_noise.py +6 -6
- {exosim-2.2.0 → exosim-2.2.2}/src/exosim/tasks/sed/download_sed.py +16 -3
- {exosim-2.2.0 → exosim-2.2.2}/src/exosim/tasks/subexposures/instantaneous_read_out.py +1 -1
- {exosim-2.2.0 → exosim-2.2.2}/src/exosim/tasks/subexposures/prepare_instantaneous_read_out.py +1 -44
- {exosim-2.2.0 → exosim-2.2.2}/src/exosim/tools/dark_current_map.py +9 -7
- {exosim-2.2.0 → exosim-2.2.2}/src/exosim/tools/pixels_non_linearity_from_correction.py +18 -18
- {exosim-2.2.0 → exosim-2.2.2}/src/exosim/utils/focal_plane_locations.py +17 -7
- {exosim-2.2.0 → exosim-2.2.2}/src/exosim.egg-info/PKG-INFO +12 -10
- {exosim-2.2.0 → exosim-2.2.2}/src/exosim.egg-info/requires.txt +1 -9
- {exosim-2.2.0 → exosim-2.2.2}/src/exosim.egg-info/scm_file_list.json +20 -11
- exosim-2.2.2/src/exosim.egg-info/scm_version.json +8 -0
- exosim-2.2.0/CHANGELOG.rst +0 -135
- exosim-2.2.0/scripts/changelog_extract.py +0 -51
- exosim-2.2.0/src/exosim.egg-info/scm_version.json +0 -8
- {exosim-2.2.0 → exosim-2.2.2}/.gitignore +0 -0
- {exosim-2.2.0 → exosim-2.2.2}/CODE_OF_CONDUCT.md +0 -0
- {exosim-2.2.0 → exosim-2.2.2}/LICENSE +0 -0
- {exosim-2.2.0 → exosim-2.2.2}/MANIFEST.in +0 -0
- {exosim-2.2.0 → exosim-2.2.2}/setup.cfg +0 -0
- {exosim-2.2.0 → exosim-2.2.2}/src/exosim/__init__.py +0 -0
- {exosim-2.2.0 → exosim-2.2.2}/src/exosim/data/Zodi_map.hdf5 +0 -0
- {exosim-2.2.0 → exosim-2.2.2}/src/exosim/exosim.py +0 -0
- {exosim-2.2.0 → exosim-2.2.2}/src/exosim/log/__init__.py +0 -0
- {exosim-2.2.0 → exosim-2.2.2}/src/exosim/log/logger.py +0 -0
- {exosim-2.2.0 → exosim-2.2.2}/src/exosim/log/structlog_config.py +0 -0
- {exosim-2.2.0 → exosim-2.2.2}/src/exosim/models/__init__.py +0 -0
- {exosim-2.2.0 → exosim-2.2.2}/src/exosim/models/utils/__init__.py +0 -0
- {exosim-2.2.0 → exosim-2.2.2}/src/exosim/models/utils/cached_data.py +0 -0
- {exosim-2.2.0 → exosim-2.2.2}/src/exosim/output/__init__.py +0 -0
- {exosim-2.2.0 → exosim-2.2.2}/src/exosim/output/hdf5/__init__.py +0 -0
- {exosim-2.2.0 → exosim-2.2.2}/src/exosim/output/hdf5/hdf5.py +0 -0
- {exosim-2.2.0 → exosim-2.2.2}/src/exosim/output/hdf5/utils.py +0 -0
- {exosim-2.2.0 → exosim-2.2.2}/src/exosim/output/output.py +0 -0
- {exosim-2.2.0 → exosim-2.2.2}/src/exosim/output/set_output.py +0 -0
- {exosim-2.2.0 → exosim-2.2.2}/src/exosim/output/utils.py +0 -0
- {exosim-2.2.0 → exosim-2.2.2}/src/exosim/plots/__init__.py +0 -0
- {exosim-2.2.0 → exosim-2.2.2}/src/exosim/plots/ndrs_plotter.py +0 -0
- {exosim-2.2.0 → exosim-2.2.2}/src/exosim/plots/plotter.py +0 -0
- {exosim-2.2.0 → exosim-2.2.2}/src/exosim/plots/radiometric_plotter.py +0 -0
- {exosim-2.2.0 → exosim-2.2.2}/src/exosim/plots/sub_exposures_plotter.py +0 -0
- {exosim-2.2.0 → exosim-2.2.2}/src/exosim/plots/utils.py +0 -0
- {exosim-2.2.0 → exosim-2.2.2}/src/exosim/py.typed +0 -0
- {exosim-2.2.0 → exosim-2.2.2}/src/exosim/recipes/__init__.py +0 -0
- {exosim-2.2.0 → exosim-2.2.2}/src/exosim/recipes/create_ndrs.py +0 -0
- {exosim-2.2.0 → exosim-2.2.2}/src/exosim/recipes/create_sub_exposures.py +0 -0
- {exosim-2.2.0 → exosim-2.2.2}/src/exosim/recipes/simulate_observation.py +0 -0
- {exosim-2.2.0 → exosim-2.2.2}/src/exosim/tasks/__init__.py +0 -0
- {exosim-2.2.0 → exosim-2.2.2}/src/exosim/tasks/astrosignal/__init__.py +0 -0
- {exosim-2.2.0 → exosim-2.2.2}/src/exosim/tasks/astrosignal/apply_astronomical_signal.py +0 -0
- {exosim-2.2.0 → exosim-2.2.2}/src/exosim/tasks/astrosignal/estimate_astronomical_signal.py +0 -0
- {exosim-2.2.0 → exosim-2.2.2}/src/exosim/tasks/astrosignal/find_astronomical_signals.py +0 -0
- {exosim-2.2.0 → exosim-2.2.2}/src/exosim/tasks/chain_task.py +0 -0
- {exosim-2.2.0 → exosim-2.2.2}/src/exosim/tasks/detector/__init__.py +0 -0
- {exosim-2.2.0 → exosim-2.2.2}/src/exosim/tasks/detector/add_constant_dark_current.py +0 -0
- {exosim-2.2.0 → exosim-2.2.2}/src/exosim/tasks/detector/add_dark_current_map_numpy.py +0 -0
- {exosim-2.2.0 → exosim-2.2.2}/src/exosim/tasks/detector/add_ktc.py +0 -0
- {exosim-2.2.0 → exosim-2.2.2}/src/exosim/tasks/detector/add_read_noise.py +0 -0
- {exosim-2.2.0 → exosim-2.2.2}/src/exosim/tasks/detector/add_read_noise_map_numpy.py +0 -0
- {exosim-2.2.0 → exosim-2.2.2}/src/exosim/tasks/detector/add_shot_noise.py +0 -0
- {exosim-2.2.0 → exosim-2.2.2}/src/exosim/tasks/detector/apply_dead_pixel_map.py +0 -0
- {exosim-2.2.0 → exosim-2.2.2}/src/exosim/tasks/detector/apply_dead_pixel_map_numpy.py +0 -0
- {exosim-2.2.0 → exosim-2.2.2}/src/exosim/tasks/detector/apply_simple_saturation.py +0 -0
- {exosim-2.2.0 → exosim-2.2.2}/src/exosim/tasks/detector/load_pixels_non_linearity_map.py +0 -0
- {exosim-2.2.0 → exosim-2.2.2}/src/exosim/tasks/detector/load_pixels_non_linearity_map_numpy.py +0 -0
- {exosim-2.2.0 → exosim-2.2.2}/src/exosim/tasks/foregrounds/__init__.py +0 -0
- {exosim-2.2.0 → exosim-2.2.2}/src/exosim/tasks/instrument/__init__.py +0 -0
- {exosim-2.2.0 → exosim-2.2.2}/src/exosim/tasks/instrument/apply_intra_pixel_response_function.py +0 -0
- {exosim-2.2.0 → exosim-2.2.2}/src/exosim/tasks/instrument/compute_saturation.py +0 -0
- {exosim-2.2.0 → exosim-2.2.2}/src/exosim/tasks/instrument/compute_solid_angle.py +0 -0
- {exosim-2.2.0 → exosim-2.2.2}/src/exosim/tasks/instrument/create_focal_plane.py +0 -0
- {exosim-2.2.0 → exosim-2.2.2}/src/exosim/tasks/instrument/create_intrapixel_response_function.py +0 -0
- {exosim-2.2.0 → exosim-2.2.2}/src/exosim/tasks/instrument/create_oversampled_intrapixel_response_function.py +0 -0
- {exosim-2.2.0 → exosim-2.2.2}/src/exosim/tasks/instrument/foregrounds_to_focal_plane.py +0 -0
- {exosim-2.2.0 → exosim-2.2.2}/src/exosim/tasks/instrument/load_psf.py +0 -0
- {exosim-2.2.0 → exosim-2.2.2}/src/exosim/tasks/instrument/load_psf_paos.py +0 -0
- {exosim-2.2.0 → exosim-2.2.2}/src/exosim/tasks/instrument/load_psf_paos_time_interp.py +0 -0
- {exosim-2.2.0 → exosim-2.2.2}/src/exosim/tasks/instrument/load_responsivity.py +0 -0
- {exosim-2.2.0 → exosim-2.2.2}/src/exosim/tasks/instrument/load_wavelength_solution.py +0 -0
- {exosim-2.2.0 → exosim-2.2.2}/src/exosim/tasks/instrument/populate_focal_plane.py +0 -0
- {exosim-2.2.0 → exosim-2.2.2}/src/exosim/tasks/instrument/propagate_foregrounds.py +0 -0
- {exosim-2.2.0 → exosim-2.2.2}/src/exosim/tasks/instrument/propagate_sources.py +0 -0
- {exosim-2.2.0 → exosim-2.2.2}/src/exosim/tasks/load/__init__.py +0 -0
- {exosim-2.2.0 → exosim-2.2.2}/src/exosim/tasks/load/load_optical_element.py +0 -0
- {exosim-2.2.0 → exosim-2.2.2}/src/exosim/tasks/load/load_optical_element_hdf5.py +0 -0
- {exosim-2.2.0 → exosim-2.2.2}/src/exosim/tasks/load/load_options.py +0 -0
- {exosim-2.2.0 → exosim-2.2.2}/src/exosim/tasks/load/load_source_list.py +0 -0
- {exosim-2.2.0 → exosim-2.2.2}/src/exosim/tasks/parse/__init__.py +0 -0
- {exosim-2.2.0 → exosim-2.2.2}/src/exosim/tasks/parse/parse_optical_element.py +0 -0
- {exosim-2.2.0 → exosim-2.2.2}/src/exosim/tasks/parse/parse_path.py +0 -0
- {exosim-2.2.0 → exosim-2.2.2}/src/exosim/tasks/parse/parse_source.py +0 -0
- {exosim-2.2.0 → exosim-2.2.2}/src/exosim/tasks/parse/parse_zodi.py +0 -0
- {exosim-2.2.0 → exosim-2.2.2}/src/exosim/tasks/radiometric/__init__.py +0 -0
- {exosim-2.2.0 → exosim-2.2.2}/src/exosim/tasks/radiometric/aperture_photometry.py +0 -0
- {exosim-2.2.0 → exosim-2.2.2}/src/exosim/tasks/radiometric/compute_custom_noise.py +0 -0
- {exosim-2.2.0 → exosim-2.2.2}/src/exosim/tasks/radiometric/compute_integration_time.py +0 -0
- {exosim-2.2.0 → exosim-2.2.2}/src/exosim/tasks/radiometric/compute_observation_efficiency.py +0 -0
- {exosim-2.2.0 → exosim-2.2.2}/src/exosim/tasks/radiometric/compute_observation_efficiency_from_dead_time.py +0 -0
- {exosim-2.2.0 → exosim-2.2.2}/src/exosim/tasks/radiometric/compute_photon_noise.py +0 -0
- {exosim-2.2.0 → exosim-2.2.2}/src/exosim/tasks/radiometric/compute_signals_channel.py +0 -0
- {exosim-2.2.0 → exosim-2.2.2}/src/exosim/tasks/radiometric/compute_sub_frg_signals_channel.py +0 -0
- {exosim-2.2.0 → exosim-2.2.2}/src/exosim/tasks/radiometric/compute_total_noise.py +0 -0
- {exosim-2.2.0 → exosim-2.2.2}/src/exosim/tasks/radiometric/estimate_apertures.py +0 -0
- {exosim-2.2.0 → exosim-2.2.2}/src/exosim/tasks/radiometric/estimate_spectral_binning.py +0 -0
- {exosim-2.2.0 → exosim-2.2.2}/src/exosim/tasks/radiometric/load_apertures.py +0 -0
- {exosim-2.2.0 → exosim-2.2.2}/src/exosim/tasks/radiometric/multiaccum.py +0 -0
- {exosim-2.2.0 → exosim-2.2.2}/src/exosim/tasks/radiometric/saturation_channel.py +0 -0
- {exosim-2.2.0 → exosim-2.2.2}/src/exosim/tasks/radiometric/utils/__init__.py +0 -0
- {exosim-2.2.0 → exosim-2.2.2}/src/exosim/tasks/radiometric/utils/compute_multiaccum.py +0 -0
- {exosim-2.2.0 → exosim-2.2.2}/src/exosim/tasks/radiometric/utils/compute_noise_column.py +0 -0
- {exosim-2.2.0 → exosim-2.2.2}/src/exosim/tasks/radiometric/utils/compute_photon_noise.py +0 -0
- {exosim-2.2.0 → exosim-2.2.2}/src/exosim/tasks/radiometric/utils/compute_saturation.py +0 -0
- {exosim-2.2.0 → exosim-2.2.2}/src/exosim/tasks/radiometric/utils/create_table.py +0 -0
- {exosim-2.2.0 → exosim-2.2.2}/src/exosim/tasks/radiometric/utils/update_total_noise.py +0 -0
- {exosim-2.2.0 → exosim-2.2.2}/src/exosim/tasks/sed/__init__.py +0 -0
- {exosim-2.2.0 → exosim-2.2.2}/src/exosim/tasks/sed/create_custom_source.py +0 -0
- {exosim-2.2.0 → exosim-2.2.2}/src/exosim/tasks/sed/create_planck_star.py +0 -0
- {exosim-2.2.0 → exosim-2.2.2}/src/exosim/tasks/sed/load_custom.py +0 -0
- {exosim-2.2.0 → exosim-2.2.2}/src/exosim/tasks/sed/load_phoenix.py +0 -0
- {exosim-2.2.0 → exosim-2.2.2}/src/exosim/tasks/sed/prepare_sed.py +0 -0
- {exosim-2.2.0 → exosim-2.2.2}/src/exosim/tasks/subexposures/__init__.py +0 -0
- {exosim-2.2.0 → exosim-2.2.2}/src/exosim/tasks/subexposures/add_foregrounds.py +0 -0
- {exosim-2.2.0 → exosim-2.2.2}/src/exosim/tasks/subexposures/apply_qe_map.py +0 -0
- {exosim-2.2.0 → exosim-2.2.2}/src/exosim/tasks/subexposures/compute_reading_scheme.py +0 -0
- {exosim-2.2.0 → exosim-2.2.2}/src/exosim/tasks/subexposures/estimate_ch_jitter.py +0 -0
- {exosim-2.2.0 → exosim-2.2.2}/src/exosim/tasks/subexposures/estimate_pointing_jitter.py +0 -0
- {exosim-2.2.0 → exosim-2.2.2}/src/exosim/tasks/subexposures/load_ils.py +0 -0
- {exosim-2.2.0 → exosim-2.2.2}/src/exosim/tasks/subexposures/load_qe_map.py +0 -0
- {exosim-2.2.0 → exosim-2.2.2}/src/exosim/tasks/subexposures/load_qe_map_numpy.py +0 -0
- {exosim-2.2.0 → exosim-2.2.2}/src/exosim/tasks/task.py +0 -0
- {exosim-2.2.0 → exosim-2.2.2}/src/exosim/tools/__init__.py +0 -0
- {exosim-2.2.0 → exosim-2.2.2}/src/exosim/tools/adc_gain_estimator.py +0 -0
- {exosim-2.2.0 → exosim-2.2.2}/src/exosim/tools/dead_pixels_map.py +0 -0
- {exosim-2.2.0 → exosim-2.2.2}/src/exosim/tools/exosim_tool.py +0 -0
- {exosim-2.2.0 → exosim-2.2.2}/src/exosim/tools/pixels_non_linearity.py +0 -0
- {exosim-2.2.0 → exosim-2.2.2}/src/exosim/tools/quantum_efficiency_map.py +0 -0
- {exosim-2.2.0 → exosim-2.2.2}/src/exosim/tools/readout_scheme_calculator.py +0 -0
- {exosim-2.2.0 → exosim-2.2.2}/src/exosim/utils/__init__.py +0 -0
- {exosim-2.2.0 → exosim-2.2.2}/src/exosim/utils/aperture.py +0 -0
- {exosim-2.2.0 → exosim-2.2.2}/src/exosim/utils/ascii_arts.py +0 -0
- {exosim-2.2.0 → exosim-2.2.2}/src/exosim/utils/binning.py +0 -0
- {exosim-2.2.0 → exosim-2.2.2}/src/exosim/utils/checks.py +0 -0
- {exosim-2.2.0 → exosim-2.2.2}/src/exosim/utils/convolution.py +0 -0
- {exosim-2.2.0 → exosim-2.2.2}/src/exosim/utils/grids.py +0 -0
- {exosim-2.2.0 → exosim-2.2.2}/src/exosim/utils/iterators.py +0 -0
- {exosim-2.2.0 → exosim-2.2.2}/src/exosim/utils/klass_factory.py +0 -0
- {exosim-2.2.0 → exosim-2.2.2}/src/exosim/utils/operations.py +0 -0
- {exosim-2.2.0 → exosim-2.2.2}/src/exosim/utils/output_cleaners.py +0 -0
- {exosim-2.2.0 → exosim-2.2.2}/src/exosim/utils/prepare_recipes.py +0 -0
- {exosim-2.2.0 → exosim-2.2.2}/src/exosim/utils/psf.py +0 -0
- {exosim-2.2.0 → exosim-2.2.2}/src/exosim/utils/run_config.py +0 -0
- {exosim-2.2.0 → exosim-2.2.2}/src/exosim/utils/timed_class.py +0 -0
- {exosim-2.2.0 → exosim-2.2.2}/src/exosim/utils/types.py +0 -0
- {exosim-2.2.0 → exosim-2.2.2}/src/exosim.egg-info/SOURCES.txt +0 -0
- {exosim-2.2.0 → exosim-2.2.2}/src/exosim.egg-info/dependency_links.txt +0 -0
- {exosim-2.2.0 → exosim-2.2.2}/src/exosim.egg-info/entry_points.txt +0 -0
- {exosim-2.2.0 → exosim-2.2.2}/src/exosim.egg-info/top_level.txt +0 -0
|
@@ -0,0 +1,288 @@
|
|
|
1
|
+
===========
|
|
2
|
+
Changelog
|
|
3
|
+
===========
|
|
4
|
+
|
|
5
|
+
All notable changes to this project will be documented in this file.
|
|
6
|
+
|
|
7
|
+
The format is based on Keep a Changelog (keepachangelog_), and this project adheres
|
|
8
|
+
to Semantic Versioning (semver_).
|
|
9
|
+
|
|
10
|
+
Unreleased changes live as fragments in ``changelog.d/`` and are merged here by
|
|
11
|
+
``nox -s release``. See ``docs/source/contributing/releasing.rst``.
|
|
12
|
+
|
|
13
|
+
.. scriv-insert-here
|
|
14
|
+
|
|
15
|
+
.. _changelog-2.2.2:
|
|
16
|
+
|
|
17
|
+
[2.2.2_] - Fix ACES solar-metallicity SED download
|
|
18
|
+
==================================================
|
|
19
|
+
|
|
20
|
+
Changed
|
|
21
|
+
-------
|
|
22
|
+
|
|
23
|
+
- the documentation home page now points readers who only need signal and
|
|
24
|
+
noise budgets to ExoRad 2, the radiometric model ExoSim 2 builds on
|
|
25
|
+
|
|
26
|
+
Fixed
|
|
27
|
+
-----
|
|
28
|
+
|
|
29
|
+
- ``DownloadSed`` with ``model_name="phoenix-aces"`` built a 404 URL for a
|
|
30
|
+
solar-metallicity star: the Goettingen server names the directory and files
|
|
31
|
+
``Z-0.0`` / ``lte...-0.0...``, but the URL builder formatted ``0.0`` as
|
|
32
|
+
``+0.0``. Metallicity formatting is now routed through ``_feh_str``.
|
|
33
|
+
|
|
34
|
+
.. _changelog-2.2.1:
|
|
35
|
+
|
|
36
|
+
[2.2.1_] - Pipeline hardening
|
|
37
|
+
=============================
|
|
38
|
+
|
|
39
|
+
Changed
|
|
40
|
+
-------
|
|
41
|
+
|
|
42
|
+
- user guide and developer guide reworked for clarity: tighter prose, corrected
|
|
43
|
+
grammar, consistent sentence-case headings, and each mechanism now explains
|
|
44
|
+
the reason behind it, not just the behaviour
|
|
45
|
+
- home page, user-guide and developer-guide landing pages now share the same
|
|
46
|
+
card-based navigation with consistent line icons, rendered from
|
|
47
|
+
reStructuredText instead of hand-written HTML and clip-art
|
|
48
|
+
|
|
49
|
+
Removed
|
|
50
|
+
-------
|
|
51
|
+
|
|
52
|
+
- unused documentation dependencies from the ``docs`` extra
|
|
53
|
+
(``sphinx-rtd-theme``, ``sphinx-panels``, ``sphinxcontrib-napoleon``,
|
|
54
|
+
``nbsphinx``, ``myst-parser`` and a few transitive-only pins)
|
|
55
|
+
|
|
56
|
+
- dead duplicate ``PrepareInstantaneousReadOut.force_power_conservation`` method
|
|
57
|
+
(the live implementation is in ``InstantaneousReadOut``)
|
|
58
|
+
|
|
59
|
+
Fixed
|
|
60
|
+
-----
|
|
61
|
+
|
|
62
|
+
- ``nox -s docs`` and ``nox -s docs-live`` now install the ``docs`` extra, so the
|
|
63
|
+
documentation builds on a clean checkout (Sphinx and the theme were missing)
|
|
64
|
+
- two broken links on the user-guide landing page
|
|
65
|
+
- several ``note`` and ``warning`` admonitions that were not rendering because
|
|
66
|
+
their content was not indented
|
|
67
|
+
- broken cross-references to the installation instructions from the quick-start
|
|
68
|
+
and FAQ pages
|
|
69
|
+
- malformed XML in the custom-task example (``unit`` attributes now quoted) and a
|
|
70
|
+
duplicate documentation label for pixel non-linearity
|
|
71
|
+
- stale continuous-integration details in the contributing guide (workflow name
|
|
72
|
+
and supported Python versions)
|
|
73
|
+
- title overline/underline mismatch on the sky-sources page that newer Sphinx
|
|
74
|
+
rejects
|
|
75
|
+
- corrupted LaTeX in several task docstrings (``\frac``, ``\times`` and similar
|
|
76
|
+
were being read as escape characters), so the rendered formulae for read
|
|
77
|
+
noise, dark current noise and the dark-current map are now correct
|
|
78
|
+
- the ExoSim logo no longer overflows and clips the page header
|
|
79
|
+
|
|
80
|
+
- ``FocalPlanePlotter`` failed with ``KeyError: 'channels'`` on a normal
|
|
81
|
+
focal-plane output: it looked for ``channels/channels`` instead of
|
|
82
|
+
``channels``
|
|
83
|
+
|
|
84
|
+
- ``exosim.__branch__`` and ``exosim.__commit__`` were always ``None``: the git
|
|
85
|
+
metadata reader looked for ``.git`` one directory too shallow
|
|
86
|
+
|
|
87
|
+
- ``InstantaneousReadOut`` in memory-saving mode (``slicing=True``) crashed with
|
|
88
|
+
``AttributeError: 'InstantaneousReadOut' object has no attribute
|
|
89
|
+
'getOversampleFactors'`` whenever the pointing jitter needed sub-pixel
|
|
90
|
+
magnification; the call now uses the renamed ``get_oversample_factors``
|
|
91
|
+
|
|
92
|
+
- the target-list mode of ``RadiometricModel`` (a ``targetlist_filepath`` under
|
|
93
|
+
``sky/source``) crashed with ``KeyError: component not found``: it rebinned
|
|
94
|
+
the channel efficiencies from the file root instead of from the per-target
|
|
95
|
+
``targets/<name>/channels`` group. The recipe now runs to completion and
|
|
96
|
+
writes a radiometric table for every target in the list.
|
|
97
|
+
|
|
98
|
+
- ``RadiometricModel`` and ``CreateFocalPlane`` failed on a payload with a
|
|
99
|
+
single, unwrapped ``channel`` entry (``KeyError: component not found`` /
|
|
100
|
+
``KeyError: 'Photometer'``): the efficiency-rebinning and the
|
|
101
|
+
foreground/source signal helpers iterated the channel dictionary as if it
|
|
102
|
+
were the multi-channel mapping. Single-channel configurations now run through
|
|
103
|
+
the whole radiometric pipeline.
|
|
104
|
+
|
|
105
|
+
- ``Signal.get_slice`` / ``Signal.set_slice`` now accept a plain ``float``
|
|
106
|
+
start/end time as documented (assumed to be hours); before they raised
|
|
107
|
+
``AttributeError``
|
|
108
|
+
- ``AddGainDrift`` raises a clear ``KeyError`` when neither
|
|
109
|
+
``gain_drift_amplitude`` nor the amplitude range is configured, instead of an
|
|
110
|
+
``UnboundLocalError``
|
|
111
|
+
- ``EstimatePlanetarySignal`` raises a clear ``ValueError`` when the planet
|
|
112
|
+
``rp`` is neither a file path nor a number, instead of an
|
|
113
|
+
``UnboundLocalError``
|
|
114
|
+
- ``Channel.target_source`` raises an informative ``KeyError`` when several
|
|
115
|
+
sources are defined but none (or more than one) is flagged as the science
|
|
116
|
+
target, instead of an ``IndexError``
|
|
117
|
+
- ``RadiometricModel`` now passes the per-channel configuration to the
|
|
118
|
+
sub-foreground signal task, so the ``<contribution>_total_signal`` columns are
|
|
119
|
+
computed for every channel type
|
|
120
|
+
- ``CreateFocalPlane`` infers the wavelength grid from the channel passbands
|
|
121
|
+
(``channel``/``wl_min``/``wl_max``) when ``wl_grid`` is absent from the
|
|
122
|
+
configuration; the previous fallback looked up a non-existent ``channels`` key
|
|
123
|
+
and always used the 1-2 micron default
|
|
124
|
+
- the spectrometer focal-plane builder no longer relies on a fragile
|
|
125
|
+
buffer-level ``array == zeros`` comparison to detect a flat wavelength axis
|
|
126
|
+
(in ``CreateFocalPlaneArray._wav_osr`` and the PSF window locator); it now
|
|
127
|
+
checks the values explicitly
|
|
128
|
+
- ``locate_wavelength_windows`` raises a clear error for an unsupported PSF
|
|
129
|
+
dimensionality or channel type instead of returning ``None`` (which made the
|
|
130
|
+
caller fail with an opaque unpacking ``TypeError``)
|
|
131
|
+
- ``EstimateZodi`` no longer loops forever when the bundled ``data`` directory
|
|
132
|
+
cannot be found by walking up from the module; the search is bounded and
|
|
133
|
+
raises ``OSError`` if it fails
|
|
134
|
+
- ``AccumulateSubExposures`` corrupted the ramp of a single-exposure
|
|
135
|
+
acquisition: the first chunk read ``state_machine[-1]`` / ``dataset[-1]`` (the
|
|
136
|
+
wrapped-around last frame) as its carry-in offset. The first chunk now starts
|
|
137
|
+
from zero
|
|
138
|
+
- ``AnalogToDigital`` clips the converted signal to the ADC full scale; a bright
|
|
139
|
+
pixel above full scale with a fixed ADC gain used to wrap around on the
|
|
140
|
+
integer cast (e.g. 200000 counts became 3392 on a 16-bit ADC)
|
|
141
|
+
- ``AddCosmicRays`` no longer fails with an ``UnboundLocalError`` when the
|
|
142
|
+
configured ``interaction_shapes`` probabilities sum to less than one; the
|
|
143
|
+
event shape falls back to the last configured shape
|
|
144
|
+
- ``MergeGroups`` raises a clear error when the number of sub-exposures is not
|
|
145
|
+
``n_groups * n_ndrs`` instead of silently mis-averaging a truncated group or
|
|
146
|
+
raising ``IndexError``
|
|
147
|
+
- ``ComputeSourcesPointingOffset`` computes the source-to-pointing offset with
|
|
148
|
+
``SkyCoord.spherical_offsets_to``, so it handles the RA 0/360 wrap and the
|
|
149
|
+
``cos(dec)`` foreshortening (a plain RA/Dec difference was wrong away from the
|
|
150
|
+
equator and near RA = 0); the offset is now rounded to the nearest sub-pixel
|
|
151
|
+
rather than truncated
|
|
152
|
+
|
|
153
|
+
Security
|
|
154
|
+
--------
|
|
155
|
+
|
|
156
|
+
- refreshed the locked dependency versions to pull in security fixes for
|
|
157
|
+
``pillow``, ``requests``, ``urllib3``, ``cryptography``, ``idna``,
|
|
158
|
+
``jupyter-server``, ``jupyterlab``, ``notebook``, ``nbconvert``, ``mistune``,
|
|
159
|
+
``tornado``, ``pygments`` and the ``safety`` toolchain (``authlib``,
|
|
160
|
+
``nltk``); this clears the outstanding Dependabot alerts on ``uv.lock``. The
|
|
161
|
+
release still installs the highest compatible versions for end users, so this
|
|
162
|
+
only affects reproducible development and CI environments
|
|
163
|
+
|
|
164
|
+
.. _changelog-2.2.0:
|
|
165
|
+
|
|
166
|
+
[2.2.0_] - End-to-end simulations
|
|
167
|
+
=================================
|
|
168
|
+
|
|
169
|
+
Added
|
|
170
|
+
-----
|
|
171
|
+
|
|
172
|
+
- new recipe ``SimulateObservation`` to run the full simulation pipeline from an options file to the NDRs
|
|
173
|
+
- radiometric model now supports target-list mode
|
|
174
|
+
- new documentation section for the radiometric model with a detailed description of the pipeline and operating modes
|
|
175
|
+
- observation efficiency can now be specified in the options file
|
|
176
|
+
- ``slim_output`` option for recipes to reduce output file size by dropping intermediate data products
|
|
177
|
+
- SED download task to fetch stellar spectra from online databases (currently Phoenix models only)
|
|
178
|
+
|
|
179
|
+
Changed
|
|
180
|
+
-------
|
|
181
|
+
|
|
182
|
+
- ``fast_convolution`` now uses ``scipy.signal.fftconvolve`` for better performance and accuracy
|
|
183
|
+
- saturation time now includes the well-depth fraction; integration time is the minimum saturation time across the detector; frame time is integration time divided by observation efficiency
|
|
184
|
+
- photon noise is now computed on the observation-efficiency-corrected signal
|
|
185
|
+
- packaging and dependency management moved from Poetry to uv
|
|
186
|
+
- logging moved to ``structlog``
|
|
187
|
+
- ``wl_interpolate`` reworked to use argsort + inverse mapping, avoiding O(n^2) lookups and extra copies
|
|
188
|
+
- ExoSim can now run without any source (no input SED)
|
|
189
|
+
- versioning is now derived from git tags via setuptools-scm; releases are cut with ``nox -s release``
|
|
190
|
+
|
|
191
|
+
Fixed
|
|
192
|
+
-----
|
|
193
|
+
|
|
194
|
+
- normalization in ``Signal`` now handles custom units correctly
|
|
195
|
+
- foreground is now decimated before being added to the focal plane instead of summed
|
|
196
|
+
- inverted parameters in the wavelength-centering equation, to avoid a polynomial inversion
|
|
197
|
+
- wrong wavelength order for ``loadPsfPaos``
|
|
198
|
+
|
|
199
|
+
[2.1.1_] - CLI Fixed
|
|
200
|
+
====================
|
|
201
|
+
Fixed
|
|
202
|
+
-----
|
|
203
|
+
- missing summary for cli.
|
|
204
|
+
|
|
205
|
+
[2.1.0_] - Hello Python 3.12
|
|
206
|
+
============================
|
|
207
|
+
Added
|
|
208
|
+
-----
|
|
209
|
+
- added unit normalization in Signal
|
|
210
|
+
|
|
211
|
+
Changed
|
|
212
|
+
-------
|
|
213
|
+
- dropped support for Python 3.9 and 3.10. Now supports only Python >3.12
|
|
214
|
+
- test framework changed into pytest
|
|
215
|
+
- added default value for low frequency time grid
|
|
216
|
+
|
|
217
|
+
|
|
218
|
+
|
|
219
|
+
[2.0.1_] - stable release
|
|
220
|
+
=========================
|
|
221
|
+
Added
|
|
222
|
+
-----
|
|
223
|
+
- improved exosim CLI with new click commands
|
|
224
|
+
- option to load optical elements from .hdf5 files (LoadOpticalElementHDF5)
|
|
225
|
+
- option to parse options file replacing a custom keyword with a value (LoadOptions)
|
|
226
|
+
- added codemeta.json file for better metadata management
|
|
227
|
+
- warning for misuse of oversampling factor and intra-pixel response function
|
|
228
|
+
- added support for wavelength dependent limb darkening
|
|
229
|
+
Changed
|
|
230
|
+
-------
|
|
231
|
+
- updated citation information
|
|
232
|
+
- rp in astronomical signal is now binned with the same binning method as Signal
|
|
233
|
+
Fixed
|
|
234
|
+
-----
|
|
235
|
+
- Custom SED units and documentation (added missing angle in loadCustom.py)
|
|
236
|
+
- find keys is not case sensitive anymore
|
|
237
|
+
- cosmic rays now work for low rates
|
|
238
|
+
- fixed elliptical PSF from PAOS
|
|
239
|
+
- ADC offset implemented as trigger offset (no negative values)
|
|
240
|
+
- astronomical signal now is weighted by the stellar flux on the detector
|
|
241
|
+
|
|
242
|
+
[2.0.0-rc2_] - ADC automode fix and minor improvements
|
|
243
|
+
======================================================
|
|
244
|
+
Added
|
|
245
|
+
-----
|
|
246
|
+
- boundaries for random amplitude in gain noise
|
|
247
|
+
- option to force non-time-dependent PSF for LoadPsfPaos (`time_dependence` parameter to `False`)
|
|
248
|
+
- option to slice jitter to save memory when the focal plane is sampled at high frequencies (`slicing` parameter to `True`)
|
|
249
|
+
Changed
|
|
250
|
+
-------
|
|
251
|
+
- dependencies versions updated to support `Poetry` for Python 3.10
|
|
252
|
+
Fixed
|
|
253
|
+
-----
|
|
254
|
+
- added offset and "auto" mode to ADC
|
|
255
|
+
- removed Numba in populateFocalPlane (better numerical accuracy)
|
|
256
|
+
- interp2d replaced with RectBivariateSpline in LoadPsfPaos to support Scipy 1.10+
|
|
257
|
+
|
|
258
|
+
[2.0.0-rc1_] - Scipy compatibility fix
|
|
259
|
+
======================================
|
|
260
|
+
Added
|
|
261
|
+
-----
|
|
262
|
+
- .npy input support for pixel non-linearity coefficients (LoadPixelsNonLinearityMapNumpy)
|
|
263
|
+
- multiplicative noise simulator (AddGainNoise)
|
|
264
|
+
|
|
265
|
+
Fixed
|
|
266
|
+
-----
|
|
267
|
+
- replaced scipy.convolve with scipy.signal.convolve
|
|
268
|
+
- ADC now works with unsigned integers
|
|
269
|
+
|
|
270
|
+
[v2.0.0-rc0_] - Release Candidate
|
|
271
|
+
================================
|
|
272
|
+
Cleaned repository
|
|
273
|
+
|
|
274
|
+
.. _v2.0.0-rc0: https://github.com/arielmission-space/ExoSim2.0/releases/tag/v2.0.0-rc0
|
|
275
|
+
.. _2.0.0-rc1: https://github.com/arielmission-space/ExoSim2.0/releases/tag/v2.0.0-rc1
|
|
276
|
+
.. _2.0.0-rc2: https://github.com/arielmission-space/ExoSim2.0/releases/tag/v2.0.0-rc2
|
|
277
|
+
.. _2.0.1: https://github.com/arielmission-space/ExoSim2.0/releases/tag/v2.0.1
|
|
278
|
+
.. _2.1.0: https://github.com/arielmission-space/ExoSim2.0/releases/tag/v2.1.0
|
|
279
|
+
.. _2.1.1: https://github.com/arielmission-space/ExoSim2.0/releases/tag/v2.1.1
|
|
280
|
+
|
|
281
|
+
.. _2.2.0: https://github.com/arielmission-space/ExoSim2.0/releases/tag/v2.2.0
|
|
282
|
+
|
|
283
|
+
.. _2.2.1: https://github.com/arielmission-space/ExoSim2.0/releases/tag/v2.2.1
|
|
284
|
+
|
|
285
|
+
.. _2.2.2: https://github.com/arielmission-space/ExoSim2.0/releases/tag/v2.2.2
|
|
286
|
+
|
|
287
|
+
.. _keepachangelog: https://keepachangelog.com/en/1.0.0/
|
|
288
|
+
.. _semver: https://semver.org/spec/v2.0.0.html
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: exosim
|
|
3
|
-
Version: 2.2.
|
|
3
|
+
Version: 2.2.2
|
|
4
4
|
Summary: ExoSim 2 is the next generation of the Exoplanet Observation Simulator (ExoSim) tailored for spectro-photometric observations of transiting exoplanets from space, ground, and sub-orbital platforms. This software is a complete rewrite implemented in Python 3, embracing object-oriented design principles.
|
|
5
5
|
Author: E. Pascale, A. Bocchieri, A. Lorenzani, A. Papageorgiou
|
|
6
6
|
Author-email: "L. V. Mugnai" <mugnail@cardiff.ac.uk>
|
|
@@ -58,18 +58,10 @@ Requires-Dist: safety>=3.2.11; extra == "dev"
|
|
|
58
58
|
Requires-Dist: bandit>=1.8.0; extra == "dev"
|
|
59
59
|
Provides-Extra: docs
|
|
60
60
|
Requires-Dist: sphinx>=8.1.3; extra == "docs"
|
|
61
|
-
Requires-Dist: sphinx-
|
|
62
|
-
Requires-Dist: sphinxcontrib-napoleon; extra == "docs"
|
|
63
|
-
Requires-Dist: sphinxcontrib-jsmath; extra == "docs"
|
|
64
|
-
Requires-Dist: nbsphinx; extra == "docs"
|
|
65
|
-
Requires-Dist: sphinx-panels; extra == "docs"
|
|
61
|
+
Requires-Dist: pydata-sphinx-theme; extra == "docs"
|
|
66
62
|
Requires-Dist: sphinx-autoapi; extra == "docs"
|
|
67
63
|
Requires-Dist: sphinx-autobuild; extra == "docs"
|
|
68
64
|
Requires-Dist: sphinx-design; extra == "docs"
|
|
69
|
-
Requires-Dist: sphinxcontrib-serializinghtml; extra == "docs"
|
|
70
|
-
Requires-Dist: docutils; extra == "docs"
|
|
71
|
-
Requires-Dist: pydata-sphinx-theme; extra == "docs"
|
|
72
|
-
Requires-Dist: myst-parser>=4.0.0; extra == "docs"
|
|
73
65
|
Provides-Extra: jupyter
|
|
74
66
|
Requires-Dist: pyzmq<27,>=26; extra == "jupyter"
|
|
75
67
|
Requires-Dist: notebook; extra == "jupyter"
|
|
@@ -90,6 +82,8 @@ Dynamic: license-file
|
|
|
90
82
|
[](https://doi.org/10.1007/s10686-024-09976-2)
|
|
91
83
|
[](https://arxiv.org/abs/2501.12809)
|
|
92
84
|
[](https://emacs.gsfc.nasa.gov?cid=2504-003)
|
|
85
|
+
[](https://deepwiki.com/arielmission-space/ExoSim2-public)
|
|
86
|
+
[](https://gitdiagram.com/arielmission-space/ExoSim2-public)
|
|
93
87
|
|
|
94
88
|
|
|
95
89
|
## Introduction <a name="introduction"></a>
|
|
@@ -145,6 +139,14 @@ If you have installed ExoSim from source code, to test your ExoSim 2 installatio
|
|
|
145
139
|
|
|
146
140
|
ExoSim2 comes with an extensive documentation, which can be built using Sphinx.
|
|
147
141
|
The documentation includes a tutorial, a user guide and a reference guide.
|
|
142
|
+
The published documentation is at <https://exosim2-public.readthedocs.io/>.
|
|
143
|
+
|
|
144
|
+
An AI-generated overview of the codebase is also available on
|
|
145
|
+
[DeepWiki](https://deepwiki.com/arielmission-space/ExoSim2-public), and an
|
|
146
|
+
interactive architecture diagram on
|
|
147
|
+
[GitDiagram](https://gitdiagram.com/arielmission-space/ExoSim2-public). Both are
|
|
148
|
+
generated automatically from the code and may be out of date or inaccurate: the
|
|
149
|
+
documentation is the reference.
|
|
148
150
|
|
|
149
151
|
To build the documentation, install the needed packages first via `uv`:
|
|
150
152
|
|
|
@@ -10,6 +10,8 @@
|
|
|
10
10
|
[](https://doi.org/10.1007/s10686-024-09976-2)
|
|
11
11
|
[](https://arxiv.org/abs/2501.12809)
|
|
12
12
|
[](https://emacs.gsfc.nasa.gov?cid=2504-003)
|
|
13
|
+
[](https://deepwiki.com/arielmission-space/ExoSim2-public)
|
|
14
|
+
[](https://gitdiagram.com/arielmission-space/ExoSim2-public)
|
|
13
15
|
|
|
14
16
|
|
|
15
17
|
## Introduction <a name="introduction"></a>
|
|
@@ -65,6 +67,14 @@ If you have installed ExoSim from source code, to test your ExoSim 2 installatio
|
|
|
65
67
|
|
|
66
68
|
ExoSim2 comes with an extensive documentation, which can be built using Sphinx.
|
|
67
69
|
The documentation includes a tutorial, a user guide and a reference guide.
|
|
70
|
+
The published documentation is at <https://exosim2-public.readthedocs.io/>.
|
|
71
|
+
|
|
72
|
+
An AI-generated overview of the codebase is also available on
|
|
73
|
+
[DeepWiki](https://deepwiki.com/arielmission-space/ExoSim2-public), and an
|
|
74
|
+
interactive architecture diagram on
|
|
75
|
+
[GitDiagram](https://gitdiagram.com/arielmission-space/ExoSim2-public). Both are
|
|
76
|
+
generated automatically from the code and may be out of date or inaccurate: the
|
|
77
|
+
documentation is the reference.
|
|
68
78
|
|
|
69
79
|
To build the documentation, install the needed packages first via `uv`:
|
|
70
80
|
|
|
@@ -15,14 +15,14 @@ Full guide: `docs/source/contributing/releasing.rst`
|
|
|
15
15
|
nox -s release
|
|
16
16
|
```
|
|
17
17
|
|
|
18
|
-
It asks major/minor/patch
|
|
19
|
-
`CITATION.cff` / `codemeta.json`, commits, fast-forwards
|
|
20
|
-
`vX.Y.Z` tag.
|
|
18
|
+
It asks major/minor/patch **and a short release name**, folds the changelog
|
|
19
|
+
fragments in, updates `CITATION.cff` / `codemeta.json`, commits, fast-forwards
|
|
20
|
+
`main`, and pushes the `vX.Y.Z` tag.
|
|
21
21
|
|
|
22
22
|
- The tag triggers `.github/workflows/release.yml`:
|
|
23
|
-
build → TestPyPI → verify install → PyPI → GitHub Release
|
|
24
|
-
|
|
25
|
-
|
|
23
|
+
build → TestPyPI → verify install → PyPI → GitHub Release → clone of the
|
|
24
|
+
tag + release + wheels into `ExoSim2-public`.
|
|
25
|
+
`sync-to-public.yml` mirrors the `main` code on every push.
|
|
26
26
|
|
|
27
27
|
## One-time setup
|
|
28
28
|
|
|
@@ -40,12 +40,12 @@
|
|
|
40
40
|
"license": "https://spdx.org/licenses/BSD-3-Clause",
|
|
41
41
|
"name": "ExoSim2",
|
|
42
42
|
"programmingLanguage": "Python 3",
|
|
43
|
-
"version": "2.2.
|
|
43
|
+
"version": "2.2.2",
|
|
44
44
|
"codemeta:contIntegration": {
|
|
45
45
|
"id": "https://app.codecov.io/gh/arielmission-space/ExoSim2-public"
|
|
46
46
|
},
|
|
47
47
|
"continuousIntegration": "https://app.codecov.io/gh/arielmission-space/ExoSim2-public",
|
|
48
48
|
"issueTracker": "https://github.com/arielmission-space/ExoSim2-public/issues",
|
|
49
49
|
"referencePublication": "https://link.springer.com/article/10.1007/s10686-024-09976-2",
|
|
50
|
-
"dateModified": "2026-
|
|
50
|
+
"dateModified": "2026-11-12"
|
|
51
51
|
}
|
|
@@ -84,18 +84,10 @@ dev = [
|
|
|
84
84
|
|
|
85
85
|
docs = [
|
|
86
86
|
"sphinx>=8.1.3",
|
|
87
|
-
"sphinx-
|
|
88
|
-
"sphinxcontrib-napoleon",
|
|
89
|
-
"sphinxcontrib-jsmath",
|
|
90
|
-
"nbsphinx",
|
|
91
|
-
"sphinx-panels",
|
|
87
|
+
"pydata-sphinx-theme",
|
|
92
88
|
"sphinx-autoapi",
|
|
93
89
|
"sphinx-autobuild",
|
|
94
90
|
"sphinx-design",
|
|
95
|
-
"sphinxcontrib-serializinghtml",
|
|
96
|
-
"docutils",
|
|
97
|
-
"pydata-sphinx-theme",
|
|
98
|
-
"myst-parser>=4.0.0",
|
|
99
91
|
]
|
|
100
92
|
|
|
101
93
|
jupyter = [
|
|
@@ -323,6 +315,10 @@ exclude_lines = [
|
|
|
323
315
|
"if __name__ == \\.__main__\\.",
|
|
324
316
|
"class .*\\bProtocol\\):",
|
|
325
317
|
"@(abc\\.)?abstractmethod",
|
|
318
|
+
# numba-compiled kernels: coverage.py cannot trace into JIT-compiled code,
|
|
319
|
+
# so the decorated function bodies are excluded. They are still exercised
|
|
320
|
+
# behaviourally by the detector, sub-exposure and instrument test suites.
|
|
321
|
+
"^\\s*@(jit|njit)\\(",
|
|
326
322
|
]
|
|
327
323
|
ignore_errors = true
|
|
328
324
|
show_missing = true
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""Read the CHANGELOG.rst entry for a given version (used to build release notes).
|
|
3
|
+
|
|
4
|
+
Usage:
|
|
5
|
+
python scripts/changelog_extract.py 2.2.0 # print the entry body
|
|
6
|
+
python scripts/changelog_extract.py 2.2.0 --title # print just the title
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
from __future__ import annotations
|
|
10
|
+
|
|
11
|
+
import sys
|
|
12
|
+
from pathlib import Path
|
|
13
|
+
|
|
14
|
+
CHANGELOG = Path(__file__).resolve().parent.parent / "CHANGELOG.rst"
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
def _find_heading(lines: list[str], version: str) -> int | None:
|
|
18
|
+
for i, line in enumerate(lines):
|
|
19
|
+
if line.startswith((f"[{version}]", f"[{version}_]")):
|
|
20
|
+
return i
|
|
21
|
+
return None
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
def extract_title(version: str) -> str:
|
|
25
|
+
"""Return the human part of the heading, e.g. "CLI fixes" from
|
|
26
|
+
``[2.1.1_] - CLI fixes``. Falls back to the bare version."""
|
|
27
|
+
lines = CHANGELOG.read_text().splitlines()
|
|
28
|
+
i = _find_heading(lines, version)
|
|
29
|
+
if i is None:
|
|
30
|
+
return version
|
|
31
|
+
heading = lines[i]
|
|
32
|
+
_, _, rest = heading.partition("] - ")
|
|
33
|
+
rest = rest.strip()
|
|
34
|
+
return rest or version
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
def extract_body(version: str) -> str:
|
|
38
|
+
lines = CHANGELOG.read_text().splitlines()
|
|
39
|
+
start = _find_heading(lines, version)
|
|
40
|
+
if start is None:
|
|
41
|
+
return f"Release {version}.\n"
|
|
42
|
+
|
|
43
|
+
body: list[str] = []
|
|
44
|
+
for line in lines[start + 2 :]: # skip heading + its underline
|
|
45
|
+
stripped = line.strip()
|
|
46
|
+
if stripped.startswith("[") and "]" in stripped:
|
|
47
|
+
break
|
|
48
|
+
if stripped.startswith((".. _", ".. scriv")):
|
|
49
|
+
break
|
|
50
|
+
body.append(line)
|
|
51
|
+
|
|
52
|
+
while body and not body[0].strip():
|
|
53
|
+
body.pop(0)
|
|
54
|
+
while body and not body[-1].strip():
|
|
55
|
+
body.pop()
|
|
56
|
+
return "\n".join(body) + "\n"
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
def main() -> int:
|
|
60
|
+
args = sys.argv[1:]
|
|
61
|
+
want_title = "--title" in args
|
|
62
|
+
args = [a for a in args if a != "--title"]
|
|
63
|
+
if len(args) != 1:
|
|
64
|
+
sys.stderr.write("usage: changelog_extract.py <version> [--title]\n")
|
|
65
|
+
return 2
|
|
66
|
+
version = args[0]
|
|
67
|
+
sys.stdout.write(extract_title(version) if want_title else extract_body(version))
|
|
68
|
+
if want_title:
|
|
69
|
+
sys.stdout.write("\n")
|
|
70
|
+
return 0
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
if __name__ == "__main__":
|
|
74
|
+
raise SystemExit(main())
|
|
@@ -140,6 +140,15 @@ def choose_part(cli_part: str | None) -> str:
|
|
|
140
140
|
print(" please answer 'major', 'minor' or 'patch'")
|
|
141
141
|
|
|
142
142
|
|
|
143
|
+
def choose_title() -> str:
|
|
144
|
+
"""Ask for a short human name for the release (e.g. 'CLI fixes')."""
|
|
145
|
+
while True:
|
|
146
|
+
title = input("Release name (short, e.g. 'CLI fixes'): ").strip()
|
|
147
|
+
if title:
|
|
148
|
+
return title
|
|
149
|
+
print(" a release name is required")
|
|
150
|
+
|
|
151
|
+
|
|
143
152
|
# --------------------------------------------------------------------------- #
|
|
144
153
|
# Quality gate
|
|
145
154
|
# --------------------------------------------------------------------------- #
|
|
@@ -154,20 +163,33 @@ def quality_gate() -> None:
|
|
|
154
163
|
# --------------------------------------------------------------------------- #
|
|
155
164
|
# Changelog + metadata
|
|
156
165
|
# --------------------------------------------------------------------------- #
|
|
157
|
-
def collect_changelog(version: str) -> None:
|
|
158
|
-
|
|
166
|
+
def collect_changelog(version: str, title: str) -> None:
|
|
167
|
+
heading = f"[{version}_] - {title}"
|
|
159
168
|
|
|
160
169
|
changelog = REPO_ROOT / "CHANGELOG.rst"
|
|
170
|
+
if f"[{version}_]" in changelog.read_text():
|
|
171
|
+
raise ReleaseError(f"CHANGELOG.rst already has an entry for {version}")
|
|
172
|
+
|
|
173
|
+
# scriv >= 1.8 refuses --version together with --title. We want a named
|
|
174
|
+
# heading (not the date-based default from ``entry_title_template``), so we
|
|
175
|
+
# pass only --title and add the ``.. _changelog-<version>:`` cross-reference
|
|
176
|
+
# anchor ourselves -- scriv only emits that on the --version code path.
|
|
177
|
+
run("uv", "run", "scriv", "collect", "--title", heading)
|
|
178
|
+
|
|
161
179
|
text = changelog.read_text()
|
|
162
180
|
|
|
181
|
+
anchor = f".. _changelog-{version}:"
|
|
182
|
+
if anchor not in text:
|
|
183
|
+
text = text.replace(f"{heading}\n", f"{anchor}\n\n{heading}\n", 1)
|
|
184
|
+
|
|
163
185
|
link = f".. _{version}: {TAG_URL.format(version=version)}\n"
|
|
164
186
|
if link not in text:
|
|
165
187
|
marker = "\n.. _keepachangelog:"
|
|
166
188
|
if marker not in text:
|
|
167
189
|
raise ReleaseError("could not find the link block in CHANGELOG.rst")
|
|
168
190
|
text = text.replace(marker, f"\n{link}{marker}", 1)
|
|
169
|
-
changelog.write_text(text)
|
|
170
191
|
|
|
192
|
+
changelog.write_text(text)
|
|
171
193
|
(REPO_ROOT / "docs" / "source" / "CHANGELOG.rst").write_text(text)
|
|
172
194
|
|
|
173
195
|
|
|
@@ -204,10 +226,10 @@ def update_codemeta(version: str, today: str) -> None:
|
|
|
204
226
|
# --------------------------------------------------------------------------- #
|
|
205
227
|
# Git release
|
|
206
228
|
# --------------------------------------------------------------------------- #
|
|
207
|
-
def commit_and_tag(version: str) -> None:
|
|
229
|
+
def commit_and_tag(version: str, title: str) -> None:
|
|
208
230
|
tag = f"v{version}"
|
|
209
231
|
git("add", "-A", capture=False)
|
|
210
|
-
git("commit", "-m", f"docs: release {version}", capture=False)
|
|
232
|
+
git("commit", "-m", f"docs: release {version} — {title}", capture=False)
|
|
211
233
|
|
|
212
234
|
print("\nChanges staged for the release commit:")
|
|
213
235
|
print(git("show", "--stat", "HEAD"))
|
|
@@ -240,11 +262,17 @@ def commit_and_tag(version: str) -> None:
|
|
|
240
262
|
f"git push {REMOTE} {tag}"
|
|
241
263
|
)
|
|
242
264
|
|
|
243
|
-
git("tag", "-a", tag, "-m", f"
|
|
265
|
+
git("tag", "-a", tag, "-m", f"{version} — {title}", capture=False)
|
|
244
266
|
git("push", REMOTE, tag, capture=False)
|
|
245
267
|
|
|
246
|
-
print(f"\n✅ Tag {tag} pushed.
|
|
247
|
-
print(f"
|
|
268
|
+
print(f"\n✅ Tag {tag} pushed. The release pipeline now runs:")
|
|
269
|
+
print(f" {ACTIONS_URL}")
|
|
270
|
+
print(" build → TestPyPI → verify → PyPI → GitHub Release →")
|
|
271
|
+
print(
|
|
272
|
+
" clone of the tag + release + wheels into arielmission-space/ExoSim2-public"
|
|
273
|
+
)
|
|
274
|
+
print(f"\n GitHub Release: {TAG_URL.format(version=version)}")
|
|
275
|
+
print(f" PyPI: https://pypi.org/project/exosim/{version}/")
|
|
248
276
|
|
|
249
277
|
|
|
250
278
|
# --------------------------------------------------------------------------- #
|
|
@@ -271,8 +299,9 @@ def main(argv: list[str] | None = None) -> int:
|
|
|
271
299
|
current = latest_stable()
|
|
272
300
|
part = choose_part(args.part)
|
|
273
301
|
version = next_version(current, part)
|
|
302
|
+
title = choose_title()
|
|
274
303
|
cur_str = ".".join(str(x) for x in current)
|
|
275
|
-
print(f"\nRelease: {cur_str} -> {version} ({part})")
|
|
304
|
+
print(f"\nRelease: {cur_str} -> {version} ({part}) — {title!r}")
|
|
276
305
|
if not confirm("Proceed?"):
|
|
277
306
|
raise ReleaseError("cancelled")
|
|
278
307
|
|
|
@@ -282,10 +311,10 @@ def main(argv: list[str] | None = None) -> int:
|
|
|
282
311
|
quality_gate()
|
|
283
312
|
|
|
284
313
|
today = dt.date.today().isoformat()
|
|
285
|
-
collect_changelog(version)
|
|
314
|
+
collect_changelog(version, title)
|
|
286
315
|
update_citation(version, today)
|
|
287
316
|
update_codemeta(version, today)
|
|
288
|
-
commit_and_tag(version)
|
|
317
|
+
commit_and_tag(version, title)
|
|
289
318
|
except ReleaseError as exc:
|
|
290
319
|
print(f"\n✗ {exc}", file=sys.stderr)
|
|
291
320
|
return 1
|
|
@@ -165,7 +165,10 @@ def _get_git_info() -> tuple[str | None, str | None]:
|
|
|
165
165
|
tuple: (branch_name, commit_hash) or (None, None) if not in git repo
|
|
166
166
|
"""
|
|
167
167
|
try:
|
|
168
|
-
|
|
168
|
+
# __file__ is <root>/src/exosim/__about__.py -> walk up to <root>
|
|
169
|
+
base_dir = os.path.dirname(
|
|
170
|
+
os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
|
|
171
|
+
)
|
|
169
172
|
except NameError:
|
|
170
173
|
return None, None
|
|
171
174
|
|
|
@@ -295,13 +295,19 @@ class Channel(log.Logger):
|
|
|
295
295
|
target = [
|
|
296
296
|
source
|
|
297
297
|
for source, param in self.sources.items()
|
|
298
|
-
if
|
|
299
|
-
and param.metadata["parsed_parameters"]["source_target"]
|
|
298
|
+
if param.metadata.get("parsed_parameters", {}).get("source_target")
|
|
300
299
|
]
|
|
300
|
+
if not target:
|
|
301
|
+
self.error(
|
|
302
|
+
"Multiple sources are defined but none is flagged as the science "
|
|
303
|
+
"target. Set 'source_target' on one source in the input file."
|
|
304
|
+
)
|
|
305
|
+
raise KeyError("no source is flagged as 'source_target'")
|
|
301
306
|
if len(target) > 1:
|
|
302
307
|
self.error(
|
|
303
308
|
"More than one target source found. Please check your input file."
|
|
304
309
|
)
|
|
310
|
+
raise KeyError("more than one source is flagged as 'source_target'")
|
|
305
311
|
self.debug(f"Target source is {target[0]}")
|
|
306
312
|
return target[0]
|
|
307
313
|
|