rubin-sim 2.6.1.dev2__py3-none-any.whl
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.
- batch/compile_prenight_metadata_cache.sh +34 -0
- batch/run_auxtel_prenight_sims.sh +163 -0
- batch/run_prenight_sims.sh +239 -0
- docs/.gitignore +3 -0
- docs/Makefile +32 -0
- docs/api.rst +25 -0
- docs/conf.py +8 -0
- docs/data-api.rst +12 -0
- docs/data-download.rst +70 -0
- docs/developer.rst +14 -0
- docs/documenteer.toml +11 -0
- docs/index.rst +22 -0
- docs/installation.rst +76 -0
- docs/introduction.rst +37 -0
- docs/maf-api-batches.rst +12 -0
- docs/maf-api-db.rst +12 -0
- docs/maf-api-maf-contrib.rst +12 -0
- docs/maf-api-maps.rst +12 -0
- docs/maf-api-metricbundles.rst +12 -0
- docs/maf-api-metrics.rst +12 -0
- docs/maf-api-plots.rst +12 -0
- docs/maf-api-run-comparison.rst +12 -0
- docs/maf-api-slicers.rst +12 -0
- docs/maf-api-stackers.rst +12 -0
- docs/maf-api-utils.rst +12 -0
- docs/maf-api.rst +22 -0
- docs/maf.rst +60 -0
- docs/metric_list.py +49 -0
- docs/moving-objects-api.rst +12 -0
- docs/moving-objects.rst +22 -0
- docs/phot-utils-api.rst +12 -0
- docs/phot-utils.rst +11 -0
- docs/prenight.rst +117 -0
- docs/protoarchive.rst +276 -0
- docs/satellite-constellations-api.rst +12 -0
- docs/satellite-constellations.rst +13 -0
- docs/selfcal-api.rst +12 -0
- docs/selfcal.rst +15 -0
- docs/sim-archive-api.rst +12 -0
- docs/skybrightness-api.rst +12 -0
- docs/skybrightness.rst +23 -0
- docs/user-guide.rst +28 -0
- docs/vseqarchive-architecture.rst +438 -0
- docs/vseqarchive-setup.rst +238 -0
- docs/vseqarchive.rst +225 -0
- rubin_sim/__init__.py +7 -0
- rubin_sim/data/__init__.py +1 -0
- rubin_sim/data/rs_download_data.py +155 -0
- rubin_sim/maf/__init__.py +34 -0
- rubin_sim/maf/batches/__init__.py +18 -0
- rubin_sim/maf/batches/altaz_batch.py +161 -0
- rubin_sim/maf/batches/col_map_dict.py +274 -0
- rubin_sim/maf/batches/common.py +388 -0
- rubin_sim/maf/batches/ddf_batch.py +728 -0
- rubin_sim/maf/batches/filterchange_batch.py +182 -0
- rubin_sim/maf/batches/glance_batch.py +591 -0
- rubin_sim/maf/batches/hourglass_batch.py +79 -0
- rubin_sim/maf/batches/info_batch.py +114 -0
- rubin_sim/maf/batches/metadata_batch.py +558 -0
- rubin_sim/maf/batches/moving_objects_batch.py +1587 -0
- rubin_sim/maf/batches/openshutter_batch.py +100 -0
- rubin_sim/maf/batches/radar_limited.py +1100 -0
- rubin_sim/maf/batches/science_radar_batch.py +1910 -0
- rubin_sim/maf/batches/skycoverage.py +155 -0
- rubin_sim/maf/batches/slew_batch.py +146 -0
- rubin_sim/maf/batches/srd_batch.py +637 -0
- rubin_sim/maf/batches/time_batch.py +757 -0
- rubin_sim/maf/batches/time_sci_batch.py +105 -0
- rubin_sim/maf/batches/visitdepth_batch.py +485 -0
- rubin_sim/maf/db/__init__.py +2 -0
- rubin_sim/maf/db/add_run.py +34 -0
- rubin_sim/maf/db/results_db.py +1074 -0
- rubin_sim/maf/db/tracking_db.py +332 -0
- rubin_sim/maf/ddf_dir.py +53 -0
- rubin_sim/maf/generate_ss.py +218 -0
- rubin_sim/maf/glance_dir.py +58 -0
- rubin_sim/maf/maf_contrib/__init__.py +25 -0
- rubin_sim/maf/maf_contrib/calculate_lsst_field_visibility_astropy.py +170 -0
- rubin_sim/maf/maf_contrib/depth_limited_num_gal_metric.py +109 -0
- rubin_sim/maf/maf_contrib/example_new_metrics.py +40 -0
- rubin_sim/maf/maf_contrib/filter_pair_t_gaps_metric.py +208 -0
- rubin_sim/maf/maf_contrib/grb_transient_metric.py +249 -0
- rubin_sim/maf/maf_contrib/gw170817_det_metric.py +72 -0
- rubin_sim/maf/maf_contrib/intervals_between_obs_metric.py +68 -0
- rubin_sim/maf/maf_contrib/kne_metrics.py +473 -0
- rubin_sim/maf/maf_contrib/lss_metrics.py +45 -0
- rubin_sim/maf/maf_contrib/lss_obs_strategy/__init__.py +3 -0
- rubin_sim/maf/maf_contrib/lss_obs_strategy/constants_for_pipeline.py +73 -0
- rubin_sim/maf/maf_contrib/lss_obs_strategy/galaxy_counts_metric_extended.py +205 -0
- rubin_sim/maf/maf_contrib/lss_obs_strategy/galaxy_counts_with_pixel_calibration.py +171 -0
- rubin_sim/maf/maf_contrib/lv_dwarfs/__init__.py +1 -0
- rubin_sim/maf/maf_contrib/lv_dwarfs/lv_dwarfs_metrics.py +388 -0
- rubin_sim/maf/maf_contrib/microlensing_metric.py +593 -0
- rubin_sim/maf/maf_contrib/num_obs_in_survey_time_overlap_metric.py +43 -0
- rubin_sim/maf/maf_contrib/periodic_metric.py +51 -0
- rubin_sim/maf/maf_contrib/periodic_star_metric.py +186 -0
- rubin_sim/maf/maf_contrib/periodic_star_modulation_metric.py +236 -0
- rubin_sim/maf/maf_contrib/presto_color_kne_pop_metric.py +441 -0
- rubin_sim/maf/maf_contrib/selfcal_uniformity_metric.py +171 -0
- rubin_sim/maf/maf_contrib/star_count_mass_metric.py +64 -0
- rubin_sim/maf/maf_contrib/star_count_metric.py +56 -0
- rubin_sim/maf/maf_contrib/star_counts/__init__.py +8 -0
- rubin_sim/maf/maf_contrib/star_counts/abs_mag.py +324 -0
- rubin_sim/maf/maf_contrib/star_counts/coords.py +99 -0
- rubin_sim/maf/maf_contrib/star_counts/readme.txt +1 -0
- rubin_sim/maf/maf_contrib/star_counts/spec_type.py +91 -0
- rubin_sim/maf/maf_contrib/star_counts/starcount.py +30 -0
- rubin_sim/maf/maf_contrib/star_counts/starcount_bymass.py +93 -0
- rubin_sim/maf/maf_contrib/star_counts/stellardensity.py +59 -0
- rubin_sim/maf/maf_contrib/static_probes_fom_summary_metric.py +386 -0
- rubin_sim/maf/maf_contrib/tdes_pop_metric.py +362 -0
- rubin_sim/maf/maf_contrib/transient_ascii_sed_metric.py +652 -0
- rubin_sim/maf/maf_contrib/triplet_metric.py +156 -0
- rubin_sim/maf/maf_contrib/var_depth_metric.py +157 -0
- rubin_sim/maf/maf_contrib/xrb_metrics.py +523 -0
- rubin_sim/maf/maf_contrib/young_stellar_objects_metric.py +200 -0
- rubin_sim/maf/maf_night_report.py +200 -0
- rubin_sim/maf/make_fbs_tracking_db.py +90 -0
- rubin_sim/maf/maps/__init__.py +8 -0
- rubin_sim/maf/maps/base_map.py +72 -0
- rubin_sim/maf/maps/create_gaia_density_map.py +158 -0
- rubin_sim/maf/maps/dust_map.py +66 -0
- rubin_sim/maf/maps/dust_map_3d.py +190 -0
- rubin_sim/maf/maps/ebv_3d_hp.py +170 -0
- rubin_sim/maf/maps/ebv_hp.py +64 -0
- rubin_sim/maf/maps/gal_coords_map.py +22 -0
- rubin_sim/maf/maps/galactic_plane_priority_maps.py +210 -0
- rubin_sim/maf/maps/stellar_density_map.py +73 -0
- rubin_sim/maf/maps/trilegal_map.py +82 -0
- rubin_sim/maf/metadata_dir.py +90 -0
- rubin_sim/maf/metric_bundles/__init__.py +3 -0
- rubin_sim/maf/metric_bundles/metric_bundle.py +816 -0
- rubin_sim/maf/metric_bundles/metric_bundle_group.py +834 -0
- rubin_sim/maf/metric_bundles/mo_metric_bundle.py +646 -0
- rubin_sim/maf/metrics/__init__.py +52 -0
- rubin_sim/maf/metrics/agn_time_lag_metric.py +118 -0
- rubin_sim/maf/metrics/agnstructure.py +141 -0
- rubin_sim/maf/metrics/area_summary_metrics.py +120 -0
- rubin_sim/maf/metrics/base_metric.py +215 -0
- rubin_sim/maf/metrics/brown_dwarf_metric.py +162 -0
- rubin_sim/maf/metrics/cadence_metrics.py +400 -0
- rubin_sim/maf/metrics/calibration_metrics.py +618 -0
- rubin_sim/maf/metrics/chip_vendor_metric.py +43 -0
- rubin_sim/maf/metrics/color_slope_metrics.py +189 -0
- rubin_sim/maf/metrics/cosmology_summary_metrics.py +1212 -0
- rubin_sim/maf/metrics/coverage_metric.py +48 -0
- rubin_sim/maf/metrics/crowding_metric.py +255 -0
- rubin_sim/maf/metrics/cumulative_metric.py +46 -0
- rubin_sim/maf/metrics/dcr_metric.py +93 -0
- rubin_sim/maf/metrics/exgal_m5.py +57 -0
- rubin_sim/maf/metrics/fft_metric.py +27 -0
- rubin_sim/maf/metrics/galactic_plane_metrics.py +375 -0
- rubin_sim/maf/metrics/galplane_time_sampling_metrics.py +236 -0
- rubin_sim/maf/metrics/hourglass_metric.py +130 -0
- rubin_sim/maf/metrics/incremental_template_metric.py +255 -0
- rubin_sim/maf/metrics/kuiper_metrics.py +26 -0
- rubin_sim/maf/metrics/mo_metrics.py +1496 -0
- rubin_sim/maf/metrics/mo_summary_metrics.py +464 -0
- rubin_sim/maf/metrics/night_pointing_metric.py +70 -0
- rubin_sim/maf/metrics/optimal_m5_metric.py +94 -0
- rubin_sim/maf/metrics/pair_metric.py +69 -0
- rubin_sim/maf/metrics/periodic_detect_metric.py +133 -0
- rubin_sim/maf/metrics/phase_gap_metric.py +172 -0
- rubin_sim/maf/metrics/qso_number_counts_metric.py +138 -0
- rubin_sim/maf/metrics/scaling_metrics.py +148 -0
- rubin_sim/maf/metrics/schedview_metrics.py +39 -0
- rubin_sim/maf/metrics/season_metrics.py +344 -0
- rubin_sim/maf/metrics/simple_metrics.py +546 -0
- rubin_sim/maf/metrics/sky_sat_metric.py +18 -0
- rubin_sim/maf/metrics/sn_cadence_metric.py +104 -0
- rubin_sim/maf/metrics/sn_n_sn_metric.py +1364 -0
- rubin_sim/maf/metrics/sn_sl_metric.py +216 -0
- rubin_sim/maf/metrics/sn_snr_metric.py +715 -0
- rubin_sim/maf/metrics/snr_weight.py +24 -0
- rubin_sim/maf/metrics/star_density.py +77 -0
- rubin_sim/maf/metrics/string_count_metric.py +95 -0
- rubin_sim/maf/metrics/summary_metrics.py +201 -0
- rubin_sim/maf/metrics/surfb_metric.py +175 -0
- rubin_sim/maf/metrics/technical_metrics.py +271 -0
- rubin_sim/maf/metrics/tgaps.py +412 -0
- rubin_sim/maf/metrics/tomography_models.py +2034 -0
- rubin_sim/maf/metrics/transient_metrics.py +268 -0
- rubin_sim/maf/metrics/uniformity_metrics.py +418 -0
- rubin_sim/maf/metrics/use_metrics.py +55 -0
- rubin_sim/maf/metrics/vector_metrics.py +190 -0
- rubin_sim/maf/metrics/visit_groups_metric.py +341 -0
- rubin_sim/maf/metrics/weak_lensing_systematics_metric.py +210 -0
- rubin_sim/maf/plots/__init__.py +14 -0
- rubin_sim/maf/plots/hg_plotters.py +1117 -0
- rubin_sim/maf/plots/hourglass_plotters.py +120 -0
- rubin_sim/maf/plots/mo_plotters.py +358 -0
- rubin_sim/maf/plots/nd_plotters.py +220 -0
- rubin_sim/maf/plots/neo_distance_plotter.py +140 -0
- rubin_sim/maf/plots/night_pointing_plotter.py +96 -0
- rubin_sim/maf/plots/oned_plotters.py +114 -0
- rubin_sim/maf/plots/perceptual_rainbow.py +30 -0
- rubin_sim/maf/plots/plot_handler.py +766 -0
- rubin_sim/maf/plots/skyproj_plotters.py +540 -0
- rubin_sim/maf/plots/spatial_plotters.py +1029 -0
- rubin_sim/maf/plots/special_plotters.py +256 -0
- rubin_sim/maf/plots/two_d_plotters.py +177 -0
- rubin_sim/maf/plots/xyplotter.py +37 -0
- rubin_sim/maf/run_comparison/__init__.py +5 -0
- rubin_sim/maf/run_comparison/archive.py +584 -0
- rubin_sim/maf/run_comparison/gather_summaries.py +125 -0
- rubin_sim/maf/run_comparison/microlensing_compare.py +514 -0
- rubin_sim/maf/run_comparison/radar_plot.py +202 -0
- rubin_sim/maf/run_comparison/summary_plots.py +710 -0
- rubin_sim/maf/run_moving_calc.py +239 -0
- rubin_sim/maf/run_moving_fractions.py +128 -0
- rubin_sim/maf/run_moving_join.py +103 -0
- rubin_sim/maf/run_selfcal_metric.py +92 -0
- rubin_sim/maf/scimaf_dir.py +87 -0
- rubin_sim/maf/show_maf.py +227 -0
- rubin_sim/maf/slicers/__init__.py +13 -0
- rubin_sim/maf/slicers/base_slicer.py +513 -0
- rubin_sim/maf/slicers/base_spatial_slicer.py +202 -0
- rubin_sim/maf/slicers/healpix_sdss_slicer.py +118 -0
- rubin_sim/maf/slicers/healpix_slicer.py +189 -0
- rubin_sim/maf/slicers/healpix_subset_slicer.py +293 -0
- rubin_sim/maf/slicers/hourglass_slicer.py +37 -0
- rubin_sim/maf/slicers/mo_slicer.py +171 -0
- rubin_sim/maf/slicers/movie_slicer.py +288 -0
- rubin_sim/maf/slicers/nd_slicer.py +147 -0
- rubin_sim/maf/slicers/one_d_slicer.py +210 -0
- rubin_sim/maf/slicers/time_interval_slicers.py +283 -0
- rubin_sim/maf/slicers/uni_slicer.py +57 -0
- rubin_sim/maf/slicers/user_points_slicer.py +141 -0
- rubin_sim/maf/stackers/__init__.py +13 -0
- rubin_sim/maf/stackers/base_stacker.py +221 -0
- rubin_sim/maf/stackers/coord_stackers.py +224 -0
- rubin_sim/maf/stackers/date_stackers.py +192 -0
- rubin_sim/maf/stackers/general_stackers.py +683 -0
- rubin_sim/maf/stackers/get_col_info.py +104 -0
- rubin_sim/maf/stackers/label_stackers.py +114 -0
- rubin_sim/maf/stackers/m5_optimal_stacker.py +126 -0
- rubin_sim/maf/stackers/mo_phase.py +265 -0
- rubin_sim/maf/stackers/mo_stackers.py +486 -0
- rubin_sim/maf/stackers/n_follow_stacker.py +187 -0
- rubin_sim/maf/stackers/neo_dist_stacker.py +126 -0
- rubin_sim/maf/stackers/sdss_stackers.py +30 -0
- rubin_sim/maf/stackers/sn_stacker.py +152 -0
- rubin_sim/maf/stackers/teff_stacker.py +154 -0
- rubin_sim/maf/utils/__init__.py +6 -0
- rubin_sim/maf/utils/astrometry_utils.py +93 -0
- rubin_sim/maf/utils/generate_fov_map.py +58 -0
- rubin_sim/maf/utils/get_date_version.py +28 -0
- rubin_sim/maf/utils/maf_utils.py +212 -0
- rubin_sim/maf/utils/opsim_utils.py +259 -0
- rubin_sim/maf/utils/output_utils.py +34 -0
- rubin_sim/maf/utils/sn_n_sn_utils.py +894 -0
- rubin_sim/maf/utils/sn_utils.py +369 -0
- rubin_sim/maf/utils/stellar_mags.py +197 -0
- rubin_sim/maf/web/__init__.py +2 -0
- rubin_sim/maf/web/favicon.ico +0 -0
- rubin_sim/maf/web/maf_run_results.py +645 -0
- rubin_sim/maf/web/maf_tracking.py +139 -0
- rubin_sim/maf/web/sorttable.js +496 -0
- rubin_sim/maf/web/templates/allmetricresults.html +72 -0
- rubin_sim/maf/web/templates/configs.html +28 -0
- rubin_sim/maf/web/templates/macros.html +243 -0
- rubin_sim/maf/web/templates/master.html +294 -0
- rubin_sim/maf/web/templates/metricselect.html +91 -0
- rubin_sim/maf/web/templates/multicolor.html +147 -0
- rubin_sim/maf/web/templates/results.html +82 -0
- rubin_sim/maf/web/templates/runselect.html +58 -0
- rubin_sim/maf/web/templates/stats.html +50 -0
- rubin_sim/moving_objects/__init__.py +8 -0
- rubin_sim/moving_objects/base_obs.py +468 -0
- rubin_sim/moving_objects/cheby_fits.py +689 -0
- rubin_sim/moving_objects/cheby_values.py +231 -0
- rubin_sim/moving_objects/chebyshev_utils.py +365 -0
- rubin_sim/moving_objects/direct_obs.py +376 -0
- rubin_sim/moving_objects/make_lsst_obs.py +282 -0
- rubin_sim/moving_objects/ooephemerides.py +643 -0
- rubin_sim/moving_objects/orbits.py +507 -0
- rubin_sim/moving_objects/pre_generate.py +37 -0
- rubin_sim/moving_objects/utils.py +61 -0
- rubin_sim/phot_utils/__init__.py +7 -0
- rubin_sim/phot_utils/bandpass.py +425 -0
- rubin_sim/phot_utils/photometric_parameters.py +449 -0
- rubin_sim/phot_utils/physical_parameters.py +50 -0
- rubin_sim/phot_utils/predicted_zeropoints.py +245 -0
- rubin_sim/phot_utils/sed.py +1773 -0
- rubin_sim/phot_utils/sed_utils.py +52 -0
- rubin_sim/phot_utils/signaltonoise.py +695 -0
- rubin_sim/phot_utils/spectral_resampling.py +161 -0
- rubin_sim/satellite_constellations/__init__.py +3 -0
- rubin_sim/satellite_constellations/basis_function.py +40 -0
- rubin_sim/satellite_constellations/model_observatory.py +157 -0
- rubin_sim/satellite_constellations/sat_utils.py +488 -0
- rubin_sim/selfcal/__init__.py +4 -0
- rubin_sim/selfcal/generate_catalog.py +188 -0
- rubin_sim/selfcal/offsets.py +119 -0
- rubin_sim/selfcal/solver.py +143 -0
- rubin_sim/selfcal/star_tools.py +42 -0
- rubin_sim/sim_archive/__init__.py +14 -0
- rubin_sim/sim_archive/conda_packages.py +65 -0
- rubin_sim/sim_archive/future_vsarch.py +480 -0
- rubin_sim/sim_archive/make_snapshot.py +255 -0
- rubin_sim/sim_archive/prenight.py +216 -0
- rubin_sim/sim_archive/prenightindex.py +229 -0
- rubin_sim/sim_archive/prototype.py +1029 -0
- rubin_sim/sim_archive/sim_archive.py +680 -0
- rubin_sim/sim_archive/tempdb.py +56 -0
- rubin_sim/sim_archive/util.py +146 -0
- rubin_sim/sim_archive/vseqarchive.py +965 -0
- rubin_sim/sim_archive/vseqmetadata.py +1721 -0
- rubin_sim/skybrightness/__init__.py +5 -0
- rubin_sim/skybrightness/allsky_db.py +93 -0
- rubin_sim/skybrightness/data/ESO_Spectra/eso_tools.py +505 -0
- rubin_sim/skybrightness/data/solarSpec/package.py +22 -0
- rubin_sim/skybrightness/generate_hdf5.py +243 -0
- rubin_sim/skybrightness/interp_components.py +798 -0
- rubin_sim/skybrightness/sky_model.py +771 -0
- rubin_sim/skybrightness/twilight_func.py +83 -0
- rubin_sim/skybrightness/utils.py +91 -0
- rubin_sim-2.6.1.dev2.dist-info/METADATA +95 -0
- rubin_sim-2.6.1.dev2.dist-info/RECORD +387 -0
- rubin_sim-2.6.1.dev2.dist-info/WHEEL +5 -0
- rubin_sim-2.6.1.dev2.dist-info/entry_points.txt +24 -0
- rubin_sim-2.6.1.dev2.dist-info/licenses/LICENSE +674 -0
- rubin_sim-2.6.1.dev2.dist-info/top_level.txt +5 -0
- sql/make_vseqmeta.sql +251 -0
- tests/data/test_data.py +26 -0
- tests/data/test_ddf_grid.py +17 -0
- tests/maf/test_3x2fom.py +68 -0
- tests/maf/test_archive.py +162 -0
- tests/maf/test_basemetrics.py +99 -0
- tests/maf/test_batchcommon.py +36 -0
- tests/maf/test_batches.py +159 -0
- tests/maf/test_cadencemetrics.py +388 -0
- tests/maf/test_calibrationmetrics.py +242 -0
- tests/maf/test_color_slopes.py +71 -0
- tests/maf/test_cosmology_summaries.py +20 -0
- tests/maf/test_gathersummaries.py +48 -0
- tests/maf/test_healpixslicer.py +439 -0
- tests/maf/test_healpixsubsetslicer.py +273 -0
- tests/maf/test_hgplotters.py +145 -0
- tests/maf/test_hourglassmetric.py +33 -0
- tests/maf/test_io.py +187 -0
- tests/maf/test_json.py +169 -0
- tests/maf/test_maps.py +199 -0
- tests/maf/test_metricbundle.py +69 -0
- tests/maf/test_mometrics.py +422 -0
- tests/maf/test_movieslicer.py +216 -0
- tests/maf/test_ndslicer.py +240 -0
- tests/maf/test_neodistanceplotter.py +41 -0
- tests/maf/test_onedslicer.py +245 -0
- tests/maf/test_opsimutils.py +80 -0
- tests/maf/test_plotters.py +134 -0
- tests/maf/test_resultsdb.py +145 -0
- tests/maf/test_schedviewmetrics.py +14 -0
- tests/maf/test_simplemetrics.py +200 -0
- tests/maf/test_snmetrics.py +335 -0
- tests/maf/test_snmetrics_nsn.py +123 -0
- tests/maf/test_stackers.py +423 -0
- tests/maf/test_stellarmags.py +50 -0
- tests/maf/test_stringcount.py +26 -0
- tests/maf/test_summary_plots.py +197 -0
- tests/maf/test_summarymetrics.py +82 -0
- tests/maf/test_technicalmetrics.py +267 -0
- tests/maf/test_templatemetrics.py +86 -0
- tests/maf/test_timeintervalslicers.py +97 -0
- tests/maf/test_trackingdb.py +88 -0
- tests/maf/test_unislicer.py +116 -0
- tests/maf/test_vectormetrics.py +225 -0
- tests/maf/test_visitgroupsmetric.py +181 -0
- tests/moving_objects/test_camera.py +39 -0
- tests/moving_objects/test_chebyfits.py +188 -0
- tests/moving_objects/test_chebyshevutils.py +76 -0
- tests/moving_objects/test_chebyvalues.py +245 -0
- tests/moving_objects/test_ephemerides.py +219 -0
- tests/moving_objects/test_orbits.py +170 -0
- tests/moving_objects/test_sed_data.py +61 -0
- tests/phot_utils/test_approximatebandpasses.py +91 -0
- tests/phot_utils/test_photometricparameters.py +268 -0
- tests/phot_utils/test_photometry.py +61 -0
- tests/phot_utils/test_predicted_zeropoints.py +53 -0
- tests/phot_utils/test_read_bandpasses.py +29 -0
- tests/phot_utils/test_sed.py +368 -0
- tests/phot_utils/test_snr.py +370 -0
- tests/satellite_constellations/test_satellites.py +36 -0
- tests/sim_archive/test_make_snapshot.py +24 -0
- tests/sim_archive/test_prototype_sim_archive.py +204 -0
- tests/sim_archive/test_vseqarchive.py +947 -0
- tests/skybrightness/test_skymodel.py +359 -0
|
@@ -0,0 +1,221 @@
|
|
|
1
|
+
__all__ = ("StackerRegistry", "BaseStacker")
|
|
2
|
+
|
|
3
|
+
import inspect
|
|
4
|
+
import warnings
|
|
5
|
+
|
|
6
|
+
import numpy as np
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class StackerRegistry(type):
|
|
10
|
+
"""
|
|
11
|
+
Meta class for Stackers, to build a registry of stacker classes.
|
|
12
|
+
"""
|
|
13
|
+
|
|
14
|
+
def __init__(cls, name, bases, dict):
|
|
15
|
+
super(StackerRegistry, cls).__init__(name, bases, dict)
|
|
16
|
+
if not hasattr(cls, "registry"):
|
|
17
|
+
cls.registry = {}
|
|
18
|
+
if not hasattr(cls, "source_dict"):
|
|
19
|
+
cls.source_dict = {}
|
|
20
|
+
modname = inspect.getmodule(cls).__name__
|
|
21
|
+
if modname.startswith("rubin_sim.maf.stackers"):
|
|
22
|
+
modname = ""
|
|
23
|
+
else:
|
|
24
|
+
if len(modname.split(".")) > 1:
|
|
25
|
+
modname = ".".join(modname.split(".")[:-1]) + "."
|
|
26
|
+
else:
|
|
27
|
+
modname = modname + "."
|
|
28
|
+
stackername = modname + name
|
|
29
|
+
if stackername in cls.registry:
|
|
30
|
+
raise Exception(
|
|
31
|
+
"Redefining stacker %s! (there are >1 stackers with the same name)" % (stackername)
|
|
32
|
+
)
|
|
33
|
+
if stackername != "BaseStacker":
|
|
34
|
+
cls.registry[stackername] = cls
|
|
35
|
+
cols_added = cls.cols_added
|
|
36
|
+
for col in cols_added:
|
|
37
|
+
cls.source_dict[col] = cls
|
|
38
|
+
|
|
39
|
+
def get_class(cls, stackername):
|
|
40
|
+
return cls.registry[stackername]
|
|
41
|
+
|
|
42
|
+
def help(cls, doc=False):
|
|
43
|
+
for stackername in sorted(cls.registry):
|
|
44
|
+
if not doc:
|
|
45
|
+
print(stackername)
|
|
46
|
+
if doc:
|
|
47
|
+
print("---- ", stackername, " ----")
|
|
48
|
+
print(cls.registry[stackername].__doc__)
|
|
49
|
+
stacker = cls.registry[stackername]()
|
|
50
|
+
print(" Columns added to SimData: ", ",".join(stacker.cols_added))
|
|
51
|
+
print(" Default columns required: ", ",".join(stacker.cols_req))
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
class BaseStacker(metaclass=StackerRegistry):
|
|
55
|
+
"""Base MAF Stacker.
|
|
56
|
+
|
|
57
|
+
Stackers add columns generated at run-time to the simdata array.
|
|
58
|
+
"""
|
|
59
|
+
|
|
60
|
+
# List of the names of the columns generated by the Stacker.
|
|
61
|
+
cols_added = []
|
|
62
|
+
|
|
63
|
+
def __init__(self):
|
|
64
|
+
"""
|
|
65
|
+
Instantiate the stacker.
|
|
66
|
+
This method should be overriden by the user.
|
|
67
|
+
This serves to define the API required by MAF.
|
|
68
|
+
"""
|
|
69
|
+
# Add the list of new columns generated by the stacker
|
|
70
|
+
# as class attributes (colsAdded - above).
|
|
71
|
+
|
|
72
|
+
# List of the names of the columns required from the database
|
|
73
|
+
# (to generate the Stacker columns).
|
|
74
|
+
self.cols_req = []
|
|
75
|
+
# Optional: specify the new column types.
|
|
76
|
+
self.cols_added_dtypes = None
|
|
77
|
+
# Optional: provide a list of units for the columns
|
|
78
|
+
# defined in colsAdded.
|
|
79
|
+
self.units = [None]
|
|
80
|
+
|
|
81
|
+
def __hash__(self):
|
|
82
|
+
return None
|
|
83
|
+
|
|
84
|
+
def __eq__(self, other_stacker):
|
|
85
|
+
"""
|
|
86
|
+
Evaluate if two stackers are equivalent.
|
|
87
|
+
|
|
88
|
+
This method is required to determine if metric_bundles may be
|
|
89
|
+
evaluated at the same time, on the same data.
|
|
90
|
+
"""
|
|
91
|
+
# If the class names are different, they are not 'the same'.
|
|
92
|
+
if self.__class__.__name__ != other_stacker.__class__.__name__:
|
|
93
|
+
return False
|
|
94
|
+
# Otherwise, this is the same stacker class,
|
|
95
|
+
# but may be instantiated differently.
|
|
96
|
+
# We have to delve a little further,
|
|
97
|
+
# and compare the kwargs & attributes for each stacker.
|
|
98
|
+
state_now = dir(self)
|
|
99
|
+
for key in state_now:
|
|
100
|
+
if not key.startswith("_") and key != "registry" and key != "run" and key != "next":
|
|
101
|
+
if not hasattr(other_stacker, key):
|
|
102
|
+
return False
|
|
103
|
+
# If the attribute is from numpy, assume it's an array
|
|
104
|
+
# and test it
|
|
105
|
+
if type(getattr(self, key)).__module__ == np.__name__:
|
|
106
|
+
if not np.array_equal(getattr(self, key), getattr(other_stacker, key)):
|
|
107
|
+
return False
|
|
108
|
+
else:
|
|
109
|
+
if getattr(self, key) != getattr(other_stacker, key):
|
|
110
|
+
return False
|
|
111
|
+
return True
|
|
112
|
+
|
|
113
|
+
def __ne__(self, other_stacker):
|
|
114
|
+
"""
|
|
115
|
+
Evaluate if two stackers are not equal.
|
|
116
|
+
"""
|
|
117
|
+
if self == other_stacker:
|
|
118
|
+
return False
|
|
119
|
+
else:
|
|
120
|
+
return True
|
|
121
|
+
|
|
122
|
+
def _add_stacker_cols(self, sim_data):
|
|
123
|
+
"""
|
|
124
|
+
Add the new Stacker columns to the sim_data array.
|
|
125
|
+
If columns already present in sim_data,
|
|
126
|
+
just allows 'run' method to overwrite.
|
|
127
|
+
Returns sim_data array with these columns added
|
|
128
|
+
(so 'run' method can set their values).
|
|
129
|
+
"""
|
|
130
|
+
if not hasattr(self, "cols_added_dtypes") or self.cols_added_dtypes is None:
|
|
131
|
+
self.cols_added_dtypes = [float for col in self.cols_added]
|
|
132
|
+
# Create description of new recarray.
|
|
133
|
+
newdtype = sim_data.dtype.descr
|
|
134
|
+
cols_present = [False] * len(self.cols_added)
|
|
135
|
+
for i, (col, dtype) in enumerate(zip(self.cols_added, self.cols_added_dtypes)):
|
|
136
|
+
if col in sim_data.dtype.names:
|
|
137
|
+
if sim_data[col][0] is not None:
|
|
138
|
+
cols_present[i] = True
|
|
139
|
+
warnings.warn(
|
|
140
|
+
"Warning - column %s already present in sim_data, may be overwritten "
|
|
141
|
+
"(depending on stacker)." % (col)
|
|
142
|
+
)
|
|
143
|
+
else:
|
|
144
|
+
newdtype += [(col, dtype)]
|
|
145
|
+
new_data = np.empty(sim_data.shape, dtype=newdtype)
|
|
146
|
+
# Add references to old data.
|
|
147
|
+
for col in sim_data.dtype.names:
|
|
148
|
+
new_data[col] = sim_data[col]
|
|
149
|
+
# Were all columns present and populated with something not None?
|
|
150
|
+
# If so, then consider 'all there'.
|
|
151
|
+
if sum(cols_present) == len(self.cols_added):
|
|
152
|
+
cols_present = True
|
|
153
|
+
else:
|
|
154
|
+
cols_present = False
|
|
155
|
+
return new_data, cols_present
|
|
156
|
+
|
|
157
|
+
def run(self, sim_data, override=False):
|
|
158
|
+
"""
|
|
159
|
+
Run the stacker, adding new columns.
|
|
160
|
+
|
|
161
|
+
Parameters
|
|
162
|
+
----------
|
|
163
|
+
sim_data : `np.ndarray`, (N, M)
|
|
164
|
+
The data to be used to evaluate metrics.
|
|
165
|
+
override : `bool`, optional
|
|
166
|
+
If True, recalculate new (stacker) columns even if present.
|
|
167
|
+
If False, calculates stacker columns only if they are not present.
|
|
168
|
+
|
|
169
|
+
|
|
170
|
+
Returns
|
|
171
|
+
-------
|
|
172
|
+
sim_data : `np.ndarray`, (N, MM)
|
|
173
|
+
The input data, plus additional stacker columns.
|
|
174
|
+
"""
|
|
175
|
+
# Add new columns
|
|
176
|
+
if len(sim_data) == 0:
|
|
177
|
+
return sim_data
|
|
178
|
+
sim_data, cols_present = self._add_stacker_cols(sim_data)
|
|
179
|
+
# If override is set, it means go ahead and recalculate stacker values.
|
|
180
|
+
if override:
|
|
181
|
+
cols_present = False
|
|
182
|
+
# Run the method to calculate/add new data.
|
|
183
|
+
try:
|
|
184
|
+
return self._run(sim_data, cols_present)
|
|
185
|
+
except TypeError:
|
|
186
|
+
warnings.warn(
|
|
187
|
+
"Please update the stacker %s so that the _run method matches the current API. "
|
|
188
|
+
"This will give you the option to skip re-running stackers if the columns are "
|
|
189
|
+
"already present." % (self.__class__.__name__)
|
|
190
|
+
)
|
|
191
|
+
return self._run(sim_data)
|
|
192
|
+
|
|
193
|
+
def _run(self, sim_data, cols_present=False):
|
|
194
|
+
"""Do the work to add the new columns. This method should be overriden
|
|
195
|
+
in subclasses.
|
|
196
|
+
|
|
197
|
+
Parameters
|
|
198
|
+
----------
|
|
199
|
+
sim_data: `np.ndarray`, (N, M)
|
|
200
|
+
The observation data, provided by the MAF framework.
|
|
201
|
+
cols_present: `bool`, optional
|
|
202
|
+
Flag to indicate what to do with the columns already present in
|
|
203
|
+
the data. This will also be provided by the MAF framework --
|
|
204
|
+
but your _run method can use the value. If it is 'True' and you
|
|
205
|
+
do trust the existing value, the _run method can simply
|
|
206
|
+
return sim_data without additional calculations.
|
|
207
|
+
|
|
208
|
+
Returns
|
|
209
|
+
-------
|
|
210
|
+
sim_data : `np.ndarray`, (N, MM)
|
|
211
|
+
The simdata, with the columns added or updated
|
|
212
|
+
(or simply already present).
|
|
213
|
+
"""
|
|
214
|
+
# By moving the calculation of these columns to a separate method,
|
|
215
|
+
# we add the possibility of using stackers with pandas dataframes.
|
|
216
|
+
# The _addStackerCols method won't work with dataframes, but the
|
|
217
|
+
# _run methods are quite likely to (depending on their details),
|
|
218
|
+
# as they are just populating columns.
|
|
219
|
+
raise NotImplementedError(
|
|
220
|
+
"Not Implemented: " "the child stackers should implement their own _run methods"
|
|
221
|
+
)
|
|
@@ -0,0 +1,224 @@
|
|
|
1
|
+
__all__ = ("ra_dec2_alt_az", "GalacticStacker", "EclipticStacker", "HealpixStacker")
|
|
2
|
+
|
|
3
|
+
import healpy as hp
|
|
4
|
+
import numpy as np
|
|
5
|
+
from astropy import units as u
|
|
6
|
+
from astropy.coordinates import SkyCoord, get_sun
|
|
7
|
+
from astropy.time import Time
|
|
8
|
+
from rubin_scheduler.utils import calc_lmst
|
|
9
|
+
|
|
10
|
+
from .base_stacker import BaseStacker
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
def wrap_ra(ra):
|
|
14
|
+
"""
|
|
15
|
+
Wrap only RA values into 0-2pi (using mod).
|
|
16
|
+
|
|
17
|
+
Parameters
|
|
18
|
+
----------
|
|
19
|
+
ra : numpy.ndarray
|
|
20
|
+
RA in radians
|
|
21
|
+
|
|
22
|
+
Returns
|
|
23
|
+
-------
|
|
24
|
+
numpy.ndarray
|
|
25
|
+
Wrapped RA values, in radians.
|
|
26
|
+
"""
|
|
27
|
+
ra = ra % (2.0 * np.pi)
|
|
28
|
+
return ra
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
def ra_dec2_alt_az(ra, dec, lat, lon, mjd, altonly=False):
|
|
32
|
+
"""Convert RA/Dec (and telescope site lat/lon) to alt/az.
|
|
33
|
+
|
|
34
|
+
This uses simple equations and ignores aberation, precession, nutation.
|
|
35
|
+
|
|
36
|
+
Parameters
|
|
37
|
+
----------
|
|
38
|
+
ra : `np.ndarray`, (N,)
|
|
39
|
+
RA, in radians.
|
|
40
|
+
dec : `np.ndarray`, (N,)
|
|
41
|
+
Dec, in radians. Must be same length as `ra`.
|
|
42
|
+
lat : `float`
|
|
43
|
+
Latitude of the observatory in radians.
|
|
44
|
+
lon : `float`
|
|
45
|
+
Longitude of the observatory in radians.
|
|
46
|
+
mjd : `float`
|
|
47
|
+
Modified Julian Date.
|
|
48
|
+
altonly : `bool`, optional
|
|
49
|
+
Calculate altitude only.
|
|
50
|
+
|
|
51
|
+
Returns
|
|
52
|
+
-------
|
|
53
|
+
alt : `np.ndarray`, (N,)
|
|
54
|
+
Altitude, same length as `ra` and `dec`. Radians.
|
|
55
|
+
az : `np.ndarray`, (N,)
|
|
56
|
+
Azimuth, same length as `ra` and `dec`. Radians.
|
|
57
|
+
"""
|
|
58
|
+
lmst = calc_lmst(mjd, lon)
|
|
59
|
+
lmst = lmst / 12.0 * np.pi # convert to rad
|
|
60
|
+
ha = lmst - ra
|
|
61
|
+
sindec = np.sin(dec)
|
|
62
|
+
sinlat = np.sin(lat)
|
|
63
|
+
coslat = np.cos(lat)
|
|
64
|
+
sinalt = sindec * sinlat + np.cos(dec) * coslat * np.cos(ha)
|
|
65
|
+
# make sure sinalt is in the expected range.
|
|
66
|
+
sinalt = np.where(sinalt < -1, -1, sinalt)
|
|
67
|
+
sinalt = np.where(sinalt > 1, 1, sinalt)
|
|
68
|
+
alt = np.arcsin(sinalt)
|
|
69
|
+
if altonly:
|
|
70
|
+
az = None
|
|
71
|
+
else:
|
|
72
|
+
cosaz = (sindec - np.sin(alt) * sinlat) / (np.cos(alt) * coslat)
|
|
73
|
+
cosaz = np.where(cosaz < -1, -1, cosaz)
|
|
74
|
+
cosaz = np.where(cosaz > 1, 1, cosaz)
|
|
75
|
+
az = np.arccos(cosaz)
|
|
76
|
+
signflip = np.where(np.sin(ha) > 0)
|
|
77
|
+
az[signflip] = 2.0 * np.pi - az[signflip]
|
|
78
|
+
return alt, az
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
class GalacticStacker(BaseStacker):
|
|
82
|
+
"""Add the galactic coordinates of each RA/Dec pointing: gall, galb
|
|
83
|
+
|
|
84
|
+
Parameters
|
|
85
|
+
----------
|
|
86
|
+
ra_col : str, optional
|
|
87
|
+
Name of the RA column. Default fieldRA.
|
|
88
|
+
dec_col : str, optional
|
|
89
|
+
Name of the Dec column. Default fieldDec.
|
|
90
|
+
"""
|
|
91
|
+
|
|
92
|
+
cols_added = ["gall", "galb"]
|
|
93
|
+
|
|
94
|
+
def __init__(self, ra_col="fieldRA", dec_col="fieldDec", degrees=True):
|
|
95
|
+
self.cols_req = [ra_col, dec_col]
|
|
96
|
+
self.ra_col = ra_col
|
|
97
|
+
self.dec_col = dec_col
|
|
98
|
+
self.degrees = degrees
|
|
99
|
+
if self.degrees:
|
|
100
|
+
self.units = ["degrees", "degrees"]
|
|
101
|
+
else:
|
|
102
|
+
self.units = ["radians", "radians"]
|
|
103
|
+
|
|
104
|
+
def _run(self, sim_data, cols_present=False):
|
|
105
|
+
# raCol and DecCol in radians, gall/b in radians.
|
|
106
|
+
if cols_present:
|
|
107
|
+
# Column already present in data;
|
|
108
|
+
# assume it is correct and does not need recalculating.
|
|
109
|
+
return sim_data
|
|
110
|
+
if self.degrees:
|
|
111
|
+
c = SkyCoord(ra=sim_data[self.ra_col] * u.deg, dec=sim_data[self.dec_col] * u.deg).transform_to(
|
|
112
|
+
"galactic"
|
|
113
|
+
)
|
|
114
|
+
else:
|
|
115
|
+
c = SkyCoord(ra=sim_data[self.ra_col] * u.rad, dec=sim_data[self.dec_col] * u.rad).transform_to(
|
|
116
|
+
"galactic"
|
|
117
|
+
)
|
|
118
|
+
sim_data["gall"] = c.l.rad
|
|
119
|
+
sim_data["galb"] = c.b.rad
|
|
120
|
+
return sim_data
|
|
121
|
+
|
|
122
|
+
|
|
123
|
+
class EclipticStacker(BaseStacker):
|
|
124
|
+
"""Add the ecliptic coordinates of each RA/Dec pointing:
|
|
125
|
+
eclipLat, eclipLon
|
|
126
|
+
|
|
127
|
+
Optionally subtract off the sun's ecliptic longitude and wrap.
|
|
128
|
+
|
|
129
|
+
Parameters
|
|
130
|
+
----------
|
|
131
|
+
mjd_col : str, optional
|
|
132
|
+
Name of the MJD column. Default expMJD.
|
|
133
|
+
ra_col : str, optional
|
|
134
|
+
Name of the RA column. Default fieldRA.
|
|
135
|
+
dec_col : str, optional
|
|
136
|
+
Name of the Dec column. Default fieldDec.
|
|
137
|
+
subtract_sun_lon : bool, optional
|
|
138
|
+
Flag to subtract the sun's ecliptic longitude. Default False.
|
|
139
|
+
"""
|
|
140
|
+
|
|
141
|
+
cols_added = ["eclipLat", "eclipLon"]
|
|
142
|
+
|
|
143
|
+
def __init__(
|
|
144
|
+
self,
|
|
145
|
+
mjd_col="observationStartMJD",
|
|
146
|
+
ra_col="fieldRA",
|
|
147
|
+
dec_col="fieldDec",
|
|
148
|
+
degrees=True,
|
|
149
|
+
subtract_sun_lon=False,
|
|
150
|
+
):
|
|
151
|
+
self.cols_req = [mjd_col, ra_col, dec_col]
|
|
152
|
+
self.subtract_sun_lon = subtract_sun_lon
|
|
153
|
+
self.degrees = degrees
|
|
154
|
+
if self.degrees:
|
|
155
|
+
self.units = ["degrees", "degrees"]
|
|
156
|
+
else:
|
|
157
|
+
self.units = ["radians", "radians"]
|
|
158
|
+
self.mjd_col = mjd_col
|
|
159
|
+
self.ra_col = ra_col
|
|
160
|
+
self.dec_col = dec_col
|
|
161
|
+
|
|
162
|
+
def _run(self, sim_data, cols_present=False):
|
|
163
|
+
if cols_present:
|
|
164
|
+
# Column already present in data;
|
|
165
|
+
# assume it is correct and does not need recalculating.
|
|
166
|
+
return sim_data
|
|
167
|
+
for i in np.arange(sim_data.size):
|
|
168
|
+
if self.degrees:
|
|
169
|
+
coord = SkyCoord(
|
|
170
|
+
ra=sim_data[self.ra_col] * u.degree,
|
|
171
|
+
dec=sim_data[self.dec_col] * u.degree,
|
|
172
|
+
)
|
|
173
|
+
else:
|
|
174
|
+
coord = SkyCoord(ra=sim_data[self.ra_col] * u.rad, dec=sim_data[self.dec_col] * u.rad)
|
|
175
|
+
coord_ecl = coord.geocentricmeanecliptic
|
|
176
|
+
sim_data["eclipLat"] = coord_ecl.lat.rad
|
|
177
|
+
|
|
178
|
+
if self.subtract_sun_lon:
|
|
179
|
+
times = Time(sim_data[self.mjd_col])
|
|
180
|
+
sun = get_sun(times)
|
|
181
|
+
sun_ecl = sun.geocentricmeanecliptic
|
|
182
|
+
lon = wrap_ra(coord_ecl.lon.rad - sun_ecl.lon.rad)
|
|
183
|
+
sim_data["eclipLon"] = lon
|
|
184
|
+
else:
|
|
185
|
+
sim_data["eclipLon"] = coord_ecl.lon.rad
|
|
186
|
+
if self.degrees:
|
|
187
|
+
sim_data["eclipLon"] = np.degrees(sim_data["eclipLon"])
|
|
188
|
+
sim_data["eclipLat"] = np.degrees(sim_data["eclipLat"])
|
|
189
|
+
return sim_data
|
|
190
|
+
|
|
191
|
+
|
|
192
|
+
class HealpixStacker(BaseStacker):
|
|
193
|
+
"""Add healpix id
|
|
194
|
+
|
|
195
|
+
Parameters
|
|
196
|
+
----------
|
|
197
|
+
ra_col : str, optional
|
|
198
|
+
Name of the RA column. Default fieldRA.
|
|
199
|
+
dec_col : str, optional
|
|
200
|
+
Name of the Dec column. Default fieldDec.
|
|
201
|
+
nside : int
|
|
202
|
+
nside healpix to use. Default to 128.
|
|
203
|
+
"""
|
|
204
|
+
|
|
205
|
+
cols_added = ["ring_healpix", "nest_healpix"]
|
|
206
|
+
|
|
207
|
+
def __init__(self, ra_col: str = "fieldRA", dec_col: str = "fieldDec", nside: int = 128):
|
|
208
|
+
self.cols_req = [ra_col, dec_col]
|
|
209
|
+
self.ra_col = ra_col
|
|
210
|
+
self.dec_col = dec_col
|
|
211
|
+
self.nside = nside
|
|
212
|
+
self.units = [f"healpix (ring, nside={nside})", f"healpix (nest, nside={nside})"]
|
|
213
|
+
|
|
214
|
+
def _run(self, sim_data, cols_present=False):
|
|
215
|
+
if cols_present:
|
|
216
|
+
# Column already present in data;
|
|
217
|
+
# assume it is correct and does not need recalculating.
|
|
218
|
+
return sim_data
|
|
219
|
+
|
|
220
|
+
ra = sim_data[self.ra_col]
|
|
221
|
+
decl = sim_data[self.dec_col]
|
|
222
|
+
sim_data["ring_healpix"] = hp.ang2pix(self.nside, ra, decl, nest=False, lonlat=True)
|
|
223
|
+
sim_data["nest_healpix"] = hp.ang2pix(self.nside, ra, decl, nest=True, lonlat=True)
|
|
224
|
+
return sim_data
|
|
@@ -0,0 +1,192 @@
|
|
|
1
|
+
__all__ = (
|
|
2
|
+
"ObservationStartDatetime64Stacker",
|
|
3
|
+
"ObservationStartTimestampStacker",
|
|
4
|
+
"DayObsStacker",
|
|
5
|
+
"DayObsMJDStacker",
|
|
6
|
+
"DayObsISOStacker",
|
|
7
|
+
)
|
|
8
|
+
|
|
9
|
+
import numpy as np
|
|
10
|
+
import pandas as pd
|
|
11
|
+
from astropy.time import Time
|
|
12
|
+
|
|
13
|
+
from .base_stacker import BaseStacker
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
class ObservationStartDatetime64Stacker(BaseStacker):
|
|
17
|
+
"""Add the observation start time as a numpy.datetime64."""
|
|
18
|
+
|
|
19
|
+
cols_added = ["observationStartDatetime64"]
|
|
20
|
+
|
|
21
|
+
def __init__(
|
|
22
|
+
self,
|
|
23
|
+
mjd_col="observationStartMJD",
|
|
24
|
+
):
|
|
25
|
+
self.mjd_col = mjd_col
|
|
26
|
+
self.cols_req = [self.mjd_col]
|
|
27
|
+
self.units = [None]
|
|
28
|
+
self.cols_added_dtypes = ["datetime64[ns]"]
|
|
29
|
+
|
|
30
|
+
def _run(self, sim_data, cols_present=False):
|
|
31
|
+
if cols_present:
|
|
32
|
+
# Column already present in data; assume it is correct and does not
|
|
33
|
+
# need recalculating.
|
|
34
|
+
return sim_data
|
|
35
|
+
|
|
36
|
+
sim_data["observationStartDatetime64"] = Time(sim_data[self.mjd_col], format="mjd").datetime64
|
|
37
|
+
|
|
38
|
+
return sim_data
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
class ObservationStartTimestampStacker(BaseStacker):
|
|
42
|
+
"""Add the observation start time as a pandas.Timestamp."""
|
|
43
|
+
|
|
44
|
+
cols_added = ["start_timestamp"]
|
|
45
|
+
|
|
46
|
+
def __init__(
|
|
47
|
+
self,
|
|
48
|
+
mjd_col="observationStartMJD",
|
|
49
|
+
):
|
|
50
|
+
self.mjd_col = mjd_col
|
|
51
|
+
self.cols_req = [self.mjd_col]
|
|
52
|
+
self.units = [None]
|
|
53
|
+
self.cols_added_dtypes = ["O"]
|
|
54
|
+
|
|
55
|
+
def run(self, sim_data, override=False):
|
|
56
|
+
# Override the run from the base class, not _run,
|
|
57
|
+
# because the implementation
|
|
58
|
+
# of _add_stackers_cols in run in the base closs
|
|
59
|
+
# clobbers the type for the new column,
|
|
60
|
+
# which we really need.
|
|
61
|
+
|
|
62
|
+
visits = sim_data if isinstance(sim_data, pd.DataFrame) else pd.DataFrame(sim_data)
|
|
63
|
+
|
|
64
|
+
if "start_timestamp" in visits.columns and not override:
|
|
65
|
+
return sim_data
|
|
66
|
+
|
|
67
|
+
if len(visits[self.mjd_col]) > 0:
|
|
68
|
+
visits["start_timestamp"] = pd.to_datetime(
|
|
69
|
+
visits[self.mjd_col] + 2400000.5, origin="julian", unit="D", utc=True
|
|
70
|
+
)
|
|
71
|
+
else:
|
|
72
|
+
# If we are passed an empty series, be sure to return add an empty
|
|
73
|
+
# series of the correct type back.
|
|
74
|
+
# This is handy if the result is being passed to bokeh
|
|
75
|
+
# for plotting.
|
|
76
|
+
visits["start_timestamp"] = pd.to_datetime(2460000.5, origin="julian", unit="D", utc=True)
|
|
77
|
+
|
|
78
|
+
match sim_data:
|
|
79
|
+
case pd.DataFrame():
|
|
80
|
+
return visits
|
|
81
|
+
case dict():
|
|
82
|
+
return visits.to_dict()
|
|
83
|
+
case _:
|
|
84
|
+
return visits.to_records(index=False)
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
def _compute_day_obs_mjd(mjd):
|
|
88
|
+
day_obs_mjd = np.floor(mjd - 0.5).astype("int")
|
|
89
|
+
return day_obs_mjd
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
def _compute_day_obs_astropy_time(mjd):
|
|
93
|
+
day_obs_time = Time(_compute_day_obs_mjd(mjd), format="mjd")
|
|
94
|
+
return day_obs_time
|
|
95
|
+
|
|
96
|
+
|
|
97
|
+
def _compute_day_obs_iso8601(mjd):
|
|
98
|
+
iso_times = _compute_day_obs_astropy_time(mjd).iso
|
|
99
|
+
|
|
100
|
+
# Work both for mjd as a scalar and a numpy array
|
|
101
|
+
if isinstance(iso_times, str):
|
|
102
|
+
day_obs_iso = iso_times[:10]
|
|
103
|
+
else:
|
|
104
|
+
day_obs_iso = np.array([d[:10] for d in iso_times])
|
|
105
|
+
|
|
106
|
+
return day_obs_iso
|
|
107
|
+
|
|
108
|
+
|
|
109
|
+
def _compute_day_obs_int(mjd):
|
|
110
|
+
day_obs_int = np.array([d.replace("-", "") for d in _compute_day_obs_iso8601(mjd)])
|
|
111
|
+
|
|
112
|
+
return day_obs_int
|
|
113
|
+
|
|
114
|
+
|
|
115
|
+
class DayObsStacker(BaseStacker):
|
|
116
|
+
"""Add dayObs as, as defined by SITCOMTN-32.
|
|
117
|
+
|
|
118
|
+
Parameters
|
|
119
|
+
----------
|
|
120
|
+
mjd_col : `str`
|
|
121
|
+
The column with the observatin start MJD.
|
|
122
|
+
"""
|
|
123
|
+
|
|
124
|
+
cols_added = ["dayObs"]
|
|
125
|
+
|
|
126
|
+
def __init__(self, mjd_col="observationStartMJD"):
|
|
127
|
+
self.mjd_col = mjd_col
|
|
128
|
+
self.cols_req = [self.mjd_col]
|
|
129
|
+
self.units = ["days"]
|
|
130
|
+
self.cols_added_dtypes = [int]
|
|
131
|
+
|
|
132
|
+
def _run(self, sim_data, cols_present=False):
|
|
133
|
+
if cols_present:
|
|
134
|
+
# Column already present in data; assume it is correct and does not
|
|
135
|
+
# need recalculating.
|
|
136
|
+
return sim_data
|
|
137
|
+
|
|
138
|
+
sim_data[self.cols_added[0]] = _compute_day_obs_int(sim_data[self.mjd_col])
|
|
139
|
+
return sim_data
|
|
140
|
+
|
|
141
|
+
|
|
142
|
+
class DayObsMJDStacker(BaseStacker):
|
|
143
|
+
"""Add dayObs defined by SITCOMTN-32, as an MJD.
|
|
144
|
+
|
|
145
|
+
Parameters
|
|
146
|
+
----------
|
|
147
|
+
mjd_col : `str`
|
|
148
|
+
The column with the observatin start MJD.
|
|
149
|
+
"""
|
|
150
|
+
|
|
151
|
+
cols_added = ["day_obs_mjd"]
|
|
152
|
+
|
|
153
|
+
def __init__(self, mjd_col="observationStartMJD"):
|
|
154
|
+
self.mjd_col = mjd_col
|
|
155
|
+
self.cols_req = [self.mjd_col]
|
|
156
|
+
self.units = ["days"]
|
|
157
|
+
self.cols_added_dtypes = [int]
|
|
158
|
+
|
|
159
|
+
def _run(self, sim_data, cols_present=False):
|
|
160
|
+
if cols_present:
|
|
161
|
+
# Column already present in data; assume it is correct and does not
|
|
162
|
+
# need recalculating.
|
|
163
|
+
return sim_data
|
|
164
|
+
|
|
165
|
+
sim_data[self.cols_added[0]] = _compute_day_obs_mjd(sim_data[self.mjd_col])
|
|
166
|
+
return sim_data
|
|
167
|
+
|
|
168
|
+
|
|
169
|
+
class DayObsISOStacker(BaseStacker):
|
|
170
|
+
"""Add dayObs as defined by SITCOMTN-32, in ISO 8601 format.
|
|
171
|
+
|
|
172
|
+
Parameters
|
|
173
|
+
----------
|
|
174
|
+
mjd_col : `str`
|
|
175
|
+
The column with the observatin start MJD."""
|
|
176
|
+
|
|
177
|
+
cols_added = ["day_obs_iso8601"]
|
|
178
|
+
|
|
179
|
+
def __init__(self, mjd_col="observationStartMJD"):
|
|
180
|
+
self.mjd_col = mjd_col
|
|
181
|
+
self.cols_req = [self.mjd_col]
|
|
182
|
+
self.units = [None]
|
|
183
|
+
self.cols_added_dtypes = [(str, 10)]
|
|
184
|
+
|
|
185
|
+
def _run(self, sim_data, cols_present=False):
|
|
186
|
+
if cols_present:
|
|
187
|
+
# Column already present in data; assume it is correct and does not
|
|
188
|
+
# need recalculating.
|
|
189
|
+
return sim_data
|
|
190
|
+
|
|
191
|
+
sim_data[self.cols_added[0]] = _compute_day_obs_iso8601(sim_data[self.mjd_col])
|
|
192
|
+
return sim_data
|