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,540 @@
|
|
|
1
|
+
import abc
|
|
2
|
+
import warnings
|
|
3
|
+
from collections import defaultdict
|
|
4
|
+
from numbers import Integral
|
|
5
|
+
from weakref import WeakKeyDictionary
|
|
6
|
+
|
|
7
|
+
import astropy.units as u
|
|
8
|
+
import healpy as hp
|
|
9
|
+
import matplotlib as mpl
|
|
10
|
+
import matplotlib.pyplot as plt
|
|
11
|
+
import numpy as np
|
|
12
|
+
import numpy.ma as ma
|
|
13
|
+
import pandas as pd
|
|
14
|
+
import skyproj
|
|
15
|
+
from astropy.coordinates import SkyCoord
|
|
16
|
+
from rubin_scheduler.utils import _healbin
|
|
17
|
+
|
|
18
|
+
from .plot_handler import BasePlotter, apply_zp_norm
|
|
19
|
+
from .spatial_plotters import set_color_lims, set_color_map
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
def compute_circle_points(
|
|
23
|
+
center_ra,
|
|
24
|
+
center_decl,
|
|
25
|
+
radius=90.0,
|
|
26
|
+
start_bear=0,
|
|
27
|
+
end_bear=360,
|
|
28
|
+
step=1,
|
|
29
|
+
):
|
|
30
|
+
"""Create points along a circle or arc on a sphere
|
|
31
|
+
|
|
32
|
+
Parameters
|
|
33
|
+
----------
|
|
34
|
+
center_ra : `float`
|
|
35
|
+
R.A. of the center of the circle (deg.).
|
|
36
|
+
center_decl : `float`
|
|
37
|
+
Decl. of the center of the circle (deg.).
|
|
38
|
+
radius : float, optional
|
|
39
|
+
Radius of the circle (deg.), by default 90.0
|
|
40
|
+
start_bear : int, optional
|
|
41
|
+
Bearing (E. of N.) of the start of the circle (deg.), by default 0
|
|
42
|
+
end_bear : int, optional
|
|
43
|
+
Bearing (E. of N.) of the end of the circle (deg.), by default 360
|
|
44
|
+
step : int, optional
|
|
45
|
+
Spacing of the points along the circle (deg.), by default 1
|
|
46
|
+
|
|
47
|
+
Returns
|
|
48
|
+
-------
|
|
49
|
+
circle : `pandas.DataFrame`
|
|
50
|
+
DataFrame with points in the circle.
|
|
51
|
+
"""
|
|
52
|
+
ras = []
|
|
53
|
+
decls = []
|
|
54
|
+
|
|
55
|
+
bearing_angles = np.arange(start_bear, end_bear + step, step) * u.deg
|
|
56
|
+
center_coords = SkyCoord(center_ra * u.deg, center_decl * u.deg)
|
|
57
|
+
circle_coords = center_coords.directional_offset_by(bearing_angles, radius * u.deg)
|
|
58
|
+
bearings = bearing_angles.value.tolist()
|
|
59
|
+
ras = circle_coords.ra.deg.tolist()
|
|
60
|
+
decls = circle_coords.dec.deg.tolist()
|
|
61
|
+
|
|
62
|
+
# de-normalize RA so there are no large jumps, which can
|
|
63
|
+
# confuse cartopy + matplotlib
|
|
64
|
+
|
|
65
|
+
previous_ra = ras[0]
|
|
66
|
+
for ra_index in range(1, len(ras)):
|
|
67
|
+
if ras[ra_index] - previous_ra > 180:
|
|
68
|
+
ras[ra_index] -= 360
|
|
69
|
+
if ras[ra_index] - previous_ra < -180:
|
|
70
|
+
ras[ra_index] += 360
|
|
71
|
+
previous_ra = ras[ra_index]
|
|
72
|
+
|
|
73
|
+
circle = pd.DataFrame(
|
|
74
|
+
{
|
|
75
|
+
"bearing": bearings,
|
|
76
|
+
"ra": ras,
|
|
77
|
+
"decl": decls,
|
|
78
|
+
}
|
|
79
|
+
).set_index("bearing")
|
|
80
|
+
|
|
81
|
+
return circle
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
class SkyprojPlotter(BasePlotter, abc.ABC):
|
|
85
|
+
"""Base class for all plotters that use the skyproj module."""
|
|
86
|
+
|
|
87
|
+
# Store a mapping between figures and existing SkyprojPlotters, but use
|
|
88
|
+
# weak keys so that the figure can be cleaned up by the garbage collector,
|
|
89
|
+
# and when it is entry in the dictionary automatically deleted.
|
|
90
|
+
skyproj_instances = WeakKeyDictionary()
|
|
91
|
+
|
|
92
|
+
default_decorations = ["ecliptic", "galactic_plane"]
|
|
93
|
+
|
|
94
|
+
default_colorbar_kwargs = {
|
|
95
|
+
"location": "bottom",
|
|
96
|
+
"shrink": 0.75,
|
|
97
|
+
"aspect": 25,
|
|
98
|
+
"pad": 0.1,
|
|
99
|
+
"orientation": "horizontal",
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
ecliptic_kwargs = {"edgecolor": "green"}
|
|
103
|
+
galactic_plane_kwargs = {"edgecolor": "blue"}
|
|
104
|
+
sun_kwargs = {"color": "yellow"}
|
|
105
|
+
moon_kwargs = {"color": "orange"}
|
|
106
|
+
horizon_kwargs = {"edgecolor": "black", "linewidth": 3}
|
|
107
|
+
|
|
108
|
+
def __init__(self):
|
|
109
|
+
super().__init__()
|
|
110
|
+
# Customize our plotters members for our new plot
|
|
111
|
+
|
|
112
|
+
self.plot_type = "Skyproj"
|
|
113
|
+
self.default_plot_dict = {}
|
|
114
|
+
self.default_plot_dict.update(
|
|
115
|
+
{
|
|
116
|
+
"subplot": 111,
|
|
117
|
+
"skyproj": skyproj.MollweideSkyproj,
|
|
118
|
+
"skyproj_kwargs": {"lon_0": 0},
|
|
119
|
+
"decorations": self.default_decorations,
|
|
120
|
+
"title": None,
|
|
121
|
+
"xlabel": None,
|
|
122
|
+
"label": None,
|
|
123
|
+
"labelsize": None,
|
|
124
|
+
"fontsize": None,
|
|
125
|
+
"figsize": None,
|
|
126
|
+
}
|
|
127
|
+
)
|
|
128
|
+
self._initialize_plot_dict({})
|
|
129
|
+
self.figure = None
|
|
130
|
+
|
|
131
|
+
def _initialize_plot_dict(self, user_plot_dict):
|
|
132
|
+
# Use a defaultdict so that everything not explicitly set return None.
|
|
133
|
+
def return_none():
|
|
134
|
+
return None
|
|
135
|
+
|
|
136
|
+
self.plot_dict = defaultdict(return_none)
|
|
137
|
+
self.plot_dict.update(self.default_plot_dict)
|
|
138
|
+
self.plot_dict.update(user_plot_dict)
|
|
139
|
+
|
|
140
|
+
def _prepare_skyproj(self, fig=None):
|
|
141
|
+
# Exctract elemens of plot_dict that need to be passed to plt.figure
|
|
142
|
+
fig_kwargs = {k: v for k, v in self.plot_dict.items() if k in ["figsize"]}
|
|
143
|
+
|
|
144
|
+
self.figure = plt.figure(**fig_kwargs) if fig is None else fig
|
|
145
|
+
|
|
146
|
+
# Normalize subplot specification,
|
|
147
|
+
# so that it can be set in either (single) integer form or tuple form.
|
|
148
|
+
# This is needed so that the same subplot set by different ways will be
|
|
149
|
+
# stored in the same key in the instance dictionary.
|
|
150
|
+
subplot_in = self.plot_dict["subplot"]
|
|
151
|
+
in_integral_form = isinstance(subplot_in, Integral) and len(str(subplot_in)) == 3
|
|
152
|
+
subplot = tuple(map(int, str(subplot_in))) if in_integral_form else tuple(subplot_in)
|
|
153
|
+
|
|
154
|
+
# If there is an existing instance of SkyprojPlotter (or one of its
|
|
155
|
+
# subclasses), reuse it.
|
|
156
|
+
# Otherwise, create a new one and store it so that it may be reused.
|
|
157
|
+
if self.figure not in self.skyproj_instances:
|
|
158
|
+
self.skyproj_instances[self.figure] = {}
|
|
159
|
+
|
|
160
|
+
if subplot in self.skyproj_instances[self.figure]:
|
|
161
|
+
existing_instance = self.skyproj_instances[self.figure][subplot]
|
|
162
|
+
assert isinstance(existing_instance, self.plot_dict["skyproj"])
|
|
163
|
+
self.skyproj = existing_instance
|
|
164
|
+
else:
|
|
165
|
+
# This instance of Axis will get deleted and replaced when the
|
|
166
|
+
# corresponding SkyPlot class is created, but this instances is
|
|
167
|
+
# needed so SkyPlot will put its instance in the correct relation
|
|
168
|
+
# with its figure.
|
|
169
|
+
ax = self.figure.add_subplot(*subplot)
|
|
170
|
+
self.skyproj = self.plot_dict["skyproj"](ax=ax, **self.plot_dict["skyproj_kwargs"])
|
|
171
|
+
self.skyproj_instances[self.figure][subplot] = self.skyproj
|
|
172
|
+
|
|
173
|
+
def draw_circle(self, center_ra, center_decl, radius=90, **kwargs):
|
|
174
|
+
"""Draw a circle on the sphere.
|
|
175
|
+
|
|
176
|
+
Parameters
|
|
177
|
+
----------
|
|
178
|
+
center_ra : `float`
|
|
179
|
+
R.A. of the center of the circle (deg.).
|
|
180
|
+
center_decl : `float`
|
|
181
|
+
Decl. of the center of the circle (deg.).
|
|
182
|
+
radius : float, optional
|
|
183
|
+
Radius of the circle (deg.), by default 90.0
|
|
184
|
+
**kwargs
|
|
185
|
+
Additional keyword arguments passed to
|
|
186
|
+
`skyproj._Skyproj.draw_polygon`.
|
|
187
|
+
"""
|
|
188
|
+
points = compute_circle_points(center_ra, center_decl, radius)
|
|
189
|
+
self.skyproj.draw_polygon(points.ra, points.decl, **kwargs)
|
|
190
|
+
|
|
191
|
+
def draw_ecliptic(self):
|
|
192
|
+
"""Draw the ecliptic the sphere.
|
|
193
|
+
|
|
194
|
+
Parameters
|
|
195
|
+
----------
|
|
196
|
+
**kwargs
|
|
197
|
+
Keyword arguments passed to
|
|
198
|
+
`skyproj._Skyproj.draw_polygon`.
|
|
199
|
+
"""
|
|
200
|
+
ecliptic_pole = SkyCoord(lon=0 * u.degree, lat=90 * u.degree, frame="geocentricmeanecliptic").icrs
|
|
201
|
+
self.draw_circle(ecliptic_pole.ra.deg, ecliptic_pole.dec.deg, **self.ecliptic_kwargs)
|
|
202
|
+
|
|
203
|
+
def draw_galactic_plane(self):
|
|
204
|
+
"""Draw the galactic plane the sphere.
|
|
205
|
+
|
|
206
|
+
Parameters
|
|
207
|
+
----------
|
|
208
|
+
**kwargs
|
|
209
|
+
Keyword arguments passed to
|
|
210
|
+
`skyproj._Skyproj.draw_polygon`.
|
|
211
|
+
"""
|
|
212
|
+
galactic_pole = SkyCoord(l=0 * u.degree, b=90 * u.degree, frame="galactic").icrs
|
|
213
|
+
self.draw_circle(galactic_pole.ra.deg, galactic_pole.dec.deg, **self.galactic_plane_kwargs)
|
|
214
|
+
|
|
215
|
+
def draw_zd(self, zd=90, **kwargs):
|
|
216
|
+
"""Draw a circle at a given zenith distance.
|
|
217
|
+
|
|
218
|
+
Parameters
|
|
219
|
+
----------
|
|
220
|
+
zd : `float`
|
|
221
|
+
The zenith distance to draw, in degrees.
|
|
222
|
+
Defaults to 90.
|
|
223
|
+
**kwargs
|
|
224
|
+
Keyword arguments passed to
|
|
225
|
+
`skyproj._Skyproj.draw_polygon`.
|
|
226
|
+
|
|
227
|
+
Notes
|
|
228
|
+
-----
|
|
229
|
+
This method relies on the site location and time (as an mjd) set in
|
|
230
|
+
the ``model_observatory`` element of the ``plot_dict``, which
|
|
231
|
+
should be of the class
|
|
232
|
+
`rubin_scheduler.scheduler.model_observatory.ModelObservatory`.
|
|
233
|
+
"""
|
|
234
|
+
if "model_observatory" not in self.plot_dict or self.plot_dict["model_observatory"] is None:
|
|
235
|
+
warnings.warn("plot_dict['model_observatory'] must be set to plot a zenith distance circle")
|
|
236
|
+
return
|
|
237
|
+
|
|
238
|
+
model_observatory = self.plot_dict["model_observatory"]
|
|
239
|
+
lmst = model_observatory.return_conditions().lmst * 360 / 24
|
|
240
|
+
latitude = model_observatory.location.lat.deg
|
|
241
|
+
self.draw_circle(lmst, latitude, zd, **kwargs)
|
|
242
|
+
|
|
243
|
+
def draw_body(self, body="sun", **kwargs):
|
|
244
|
+
"""Mark the sun or moon.
|
|
245
|
+
|
|
246
|
+
Parameters
|
|
247
|
+
----------
|
|
248
|
+
body : `str`
|
|
249
|
+
The name of the body to draw, either `sun` or `moon`.
|
|
250
|
+
Defaults to `sun`
|
|
251
|
+
**kwargs
|
|
252
|
+
Keyword arguments passed to
|
|
253
|
+
`skyproj._Skyproj.scatter`
|
|
254
|
+
|
|
255
|
+
Notes
|
|
256
|
+
-----
|
|
257
|
+
This method relies on the site location and time (as an mjd) set in
|
|
258
|
+
the ``model_observatory`` element of the ``plot_dict``, which
|
|
259
|
+
should be of the class
|
|
260
|
+
`rubin_scheduler.scheduler.model_observatory.ModelObservatory`.
|
|
261
|
+
"""
|
|
262
|
+
if "model_observatory" not in self.plot_dict or self.plot_dict["model_observatory"] is None:
|
|
263
|
+
warnings.warn(f"plot_dict['model_observatory'] must be set to plot the {body}")
|
|
264
|
+
return
|
|
265
|
+
|
|
266
|
+
mjd = self.plot_dict["model_observatory"].mjd
|
|
267
|
+
model_observatory = self.plot_dict["model_observatory"]
|
|
268
|
+
sun_moon_positions = model_observatory.almanac.get_sun_moon_positions(mjd)
|
|
269
|
+
ra = np.degrees(sun_moon_positions[f"{body}_RA"].item())
|
|
270
|
+
decl = np.degrees(sun_moon_positions[f"{body}_dec"].item())
|
|
271
|
+
self.skyproj.scatter(ra, decl, **kwargs)
|
|
272
|
+
|
|
273
|
+
def decorate(self):
|
|
274
|
+
"""Add decorations/annotations to the sky plot.
|
|
275
|
+
|
|
276
|
+
Notes
|
|
277
|
+
-----
|
|
278
|
+
For decorations that depend on the time or location of the observer
|
|
279
|
+
(e.g., the horizon and sun and moon positions)
|
|
280
|
+
this method relies on the site location and time (as an mjd) set in
|
|
281
|
+
the ``model_observatory`` element of the ``plot_dict``, which
|
|
282
|
+
should be of the class
|
|
283
|
+
`rubin_scheduler.scheduler.model_observatory.ModelObservatory`.
|
|
284
|
+
Other decorations (e.g., the ecliptic and galactic plane) can
|
|
285
|
+
be shown even when ``model_observatory`` is not set.
|
|
286
|
+
"""
|
|
287
|
+
decorations = self.plot_dict["decorations"]
|
|
288
|
+
|
|
289
|
+
if "ecliptic" in decorations:
|
|
290
|
+
self.draw_ecliptic()
|
|
291
|
+
|
|
292
|
+
if "galactic_plane" in decorations:
|
|
293
|
+
self.draw_galactic_plane()
|
|
294
|
+
|
|
295
|
+
if "sun" in decorations:
|
|
296
|
+
self.draw_body("sun", **self.sun_kwargs)
|
|
297
|
+
|
|
298
|
+
if "moon" in decorations:
|
|
299
|
+
self.draw_body("moon", **self.moon_kwargs)
|
|
300
|
+
|
|
301
|
+
if "horizon" in decorations:
|
|
302
|
+
self.draw_zd(**self.horizon_kwargs)
|
|
303
|
+
|
|
304
|
+
@abc.abstractmethod
|
|
305
|
+
def draw(self, metric_values, slicer):
|
|
306
|
+
raise NotImplementedError()
|
|
307
|
+
|
|
308
|
+
def __call__(self, metric_values, slicer, user_plot_dict, fig=None):
|
|
309
|
+
"""Make a plot.
|
|
310
|
+
|
|
311
|
+
Parameters
|
|
312
|
+
----------
|
|
313
|
+
metric_value : `numpy.ma.MaskedArray`
|
|
314
|
+
The metric values from the bundle.
|
|
315
|
+
slicer : `rubin_sim.maf.slicers.TwoDSlicer`
|
|
316
|
+
The slicer.
|
|
317
|
+
user_plot_dict: `dict`
|
|
318
|
+
Dictionary of plot parameters set by user
|
|
319
|
+
(overrides default values).
|
|
320
|
+
fig : `matplotlib.figure.Figure`
|
|
321
|
+
Matplotlib figure.
|
|
322
|
+
The default is ``None``, which starts new figure.
|
|
323
|
+
|
|
324
|
+
Returns
|
|
325
|
+
-------
|
|
326
|
+
fig : `matplotlib.figure.Figure`
|
|
327
|
+
Figure with the plot.
|
|
328
|
+
"""
|
|
329
|
+
self._initialize_plot_dict(user_plot_dict)
|
|
330
|
+
self._prepare_skyproj(fig)
|
|
331
|
+
self.draw(metric_values, slicer)
|
|
332
|
+
self.decorate()
|
|
333
|
+
|
|
334
|
+
# Do not show axis labels unless they are set explicitly
|
|
335
|
+
# or specified as decorators.
|
|
336
|
+
if self.plot_dict["xlabel"] is None:
|
|
337
|
+
if "xlabel" not in self.plot_dict["decorations"]:
|
|
338
|
+
self.skyproj.ax.set_xlabel("", visible=False)
|
|
339
|
+
else:
|
|
340
|
+
self.skyproj.ax.set_xlabel(self.plot_dict["xlabel"])
|
|
341
|
+
|
|
342
|
+
if self.plot_dict["ylabel"] is None:
|
|
343
|
+
if "ylabel" not in self.plot_dict["decorations"]:
|
|
344
|
+
self.skyproj.ax.set_ylabel("", visible=False)
|
|
345
|
+
else:
|
|
346
|
+
self.skyproj.ax.set_ylabel(self.plot_dict["ylabel"])
|
|
347
|
+
|
|
348
|
+
if self.plot_dict["label"] is not None:
|
|
349
|
+
label_kwargs = {}
|
|
350
|
+
if "fontsize" in self.plot_dict:
|
|
351
|
+
label_kwargs["fontsize"] = self.plot_dict["fontsize"]
|
|
352
|
+
if "label_loc" in self.plot_dict:
|
|
353
|
+
label_kwargs["loc"] = self.plot_dict["label_loc"]
|
|
354
|
+
self.skyproj.ax.set_title(self.plot_dict["label"], **label_kwargs)
|
|
355
|
+
|
|
356
|
+
if self.plot_dict["title"] is not None:
|
|
357
|
+
title_kwargs = {}
|
|
358
|
+
if "fontsize" in self.plot_dict:
|
|
359
|
+
title_kwargs["fontsize"] = self.plot_dict["fontsize"]
|
|
360
|
+
self.figure.suptitle(self.plot_dict["title"], **title_kwargs)
|
|
361
|
+
|
|
362
|
+
return self.figure
|
|
363
|
+
|
|
364
|
+
|
|
365
|
+
class HpxmapPlotter(SkyprojPlotter):
|
|
366
|
+
default_hpixmap_kwargs = {"zoom": False}
|
|
367
|
+
|
|
368
|
+
def __init__(self):
|
|
369
|
+
super().__init__()
|
|
370
|
+
self.default_plot_dict["colorbar"] = True
|
|
371
|
+
self.object_plotter = False
|
|
372
|
+
|
|
373
|
+
def draw_colorbar(self):
|
|
374
|
+
"""Add a color bar."""
|
|
375
|
+
plot_dict = self.plot_dict
|
|
376
|
+
|
|
377
|
+
colorbar_kwargs = {}
|
|
378
|
+
colorbar_kwargs.update(self.default_colorbar_kwargs)
|
|
379
|
+
|
|
380
|
+
if "extend" in self.plot_dict:
|
|
381
|
+
colorbar_kwargs["extendrect"] = self.plot_dict["extend"] == "neither"
|
|
382
|
+
|
|
383
|
+
if "cbar_format" in self.plot_dict:
|
|
384
|
+
colorbar_kwargs["format"] = self.plot_dict["cbar_format"]
|
|
385
|
+
|
|
386
|
+
if "cbar_orientation" in self.plot_dict:
|
|
387
|
+
colorbar_kwargs["orientation"] = self.plot_dict["cbar_orientation"]
|
|
388
|
+
match self.plot_dict["cbar_orientation"].lower():
|
|
389
|
+
case "vertical":
|
|
390
|
+
colorbar_kwargs["shrink"] = 0.5
|
|
391
|
+
colorbar_kwargs["location"] = "right"
|
|
392
|
+
case "horizontal":
|
|
393
|
+
colorbar_kwargs["location"] = "bottom"
|
|
394
|
+
case _:
|
|
395
|
+
orientation = self.plot_dict["cbar_orientation"]
|
|
396
|
+
raise NotImplementedError(f"cbar_orintation {orientation} is not supported")
|
|
397
|
+
|
|
398
|
+
colorbar = self.skyproj.draw_colorbar(**colorbar_kwargs)
|
|
399
|
+
|
|
400
|
+
colorbar.set_label(self.plot_dict["xlabel"], fontsize=self.plot_dict["fontsize"])
|
|
401
|
+
|
|
402
|
+
if "labelsize" in self.plot_dict and self.plot_dict["labelsize"] is not None:
|
|
403
|
+
colorbar.ax.tick_params(labelsize=plot_dict["labelsize"])
|
|
404
|
+
|
|
405
|
+
if "n_ticks" in self.plot_dict and self.plot_dict["n_ticks"] is not None:
|
|
406
|
+
tick_locator = mpl.ticker.MaxNLocator(nbins=plot_dict["n_ticks"])
|
|
407
|
+
colorbar.locator = tick_locator
|
|
408
|
+
colorbar.update_ticks()
|
|
409
|
+
|
|
410
|
+
# If outputing to PDF, this fixes the colorbar white stripes
|
|
411
|
+
if "cbar_edge" in self.plot_dict and self.plot_dict["cbar_edge"]:
|
|
412
|
+
colorbar.solids.set_edgecolor("face")
|
|
413
|
+
|
|
414
|
+
def decorate(self):
|
|
415
|
+
super().decorate()
|
|
416
|
+
|
|
417
|
+
if self.plot_dict["colorbar"]:
|
|
418
|
+
self.draw_colorbar()
|
|
419
|
+
|
|
420
|
+
def _transform_to_healpix(self, metric_value_in, slicer):
|
|
421
|
+
# Bin the values up on a healpix grid.
|
|
422
|
+
metric_value = _healbin(
|
|
423
|
+
slicer.slice_points["ra"],
|
|
424
|
+
slicer.slice_points["dec"],
|
|
425
|
+
metric_value_in.filled(slicer.badval),
|
|
426
|
+
nside=self.plot_dict["nside"],
|
|
427
|
+
reduce_func=self.plot_dict["reduce_func"],
|
|
428
|
+
fill_val=slicer.badval,
|
|
429
|
+
)
|
|
430
|
+
mask = np.zeros(metric_value.size)
|
|
431
|
+
mask[np.where(metric_value == slicer.badval)] = 1
|
|
432
|
+
|
|
433
|
+
metric_value = ma.array(metric_value, mask=mask)
|
|
434
|
+
return metric_value
|
|
435
|
+
|
|
436
|
+
def _compatible_color_limits(self, norm, clims):
|
|
437
|
+
# Log can't be 0
|
|
438
|
+
compatible = (norm != "log") or (clims[0] < 0 and clims[1] < 0) or (clims[0] > 0 and clims[1] > 0)
|
|
439
|
+
return compatible
|
|
440
|
+
|
|
441
|
+
def draw(self, metric_values_in, slicer):
|
|
442
|
+
"""Draw the healpix map.
|
|
443
|
+
|
|
444
|
+
Parameters
|
|
445
|
+
----------
|
|
446
|
+
metric_value : `numpy.ma.MaskedArray`
|
|
447
|
+
The metric values from the bundle.
|
|
448
|
+
slicer : `rubin_sim.maf.slicers.TwoDSlicer`
|
|
449
|
+
The slicer
|
|
450
|
+
"""
|
|
451
|
+
kwargs = {}
|
|
452
|
+
kwargs.update(self.default_hpixmap_kwargs)
|
|
453
|
+
|
|
454
|
+
# Check if we have a valid HEALpix slicer
|
|
455
|
+
if "Heal" not in slicer.slicer_name:
|
|
456
|
+
hpix_map = self._transform_to_healpix(metric_values_in, slicer)
|
|
457
|
+
else:
|
|
458
|
+
hpix_map = metric_values_in.copy()
|
|
459
|
+
|
|
460
|
+
hpix_map = apply_zp_norm(hpix_map, self.plot_dict)
|
|
461
|
+
|
|
462
|
+
if "draw_hpxmap_kwargs" in self.plot_dict:
|
|
463
|
+
kwargs.update(self.plot_dict["draw_hpxmap_kwargs"])
|
|
464
|
+
|
|
465
|
+
try:
|
|
466
|
+
kwargs["cmap"] = set_color_map(self.plot_dict)
|
|
467
|
+
except AttributeError:
|
|
468
|
+
# Probably here because an invalid cmap was set
|
|
469
|
+
pass
|
|
470
|
+
|
|
471
|
+
if self.plot_dict["log_scale"]:
|
|
472
|
+
if "norm" in kwargs and kwargs["norm"] != "log":
|
|
473
|
+
raise ValueError("Contradictory values for color scale normalization set.")
|
|
474
|
+
kwargs["norm"] = "log"
|
|
475
|
+
|
|
476
|
+
clims = set_color_lims(hpix_map, self.plot_dict)
|
|
477
|
+
if "norm" not in kwargs or self._compatible_color_limits(kwargs["norm"], clims):
|
|
478
|
+
kwargs["vmin"] = clims[0]
|
|
479
|
+
kwargs["vmax"] = clims[1]
|
|
480
|
+
else:
|
|
481
|
+
warnings.warn(
|
|
482
|
+
"Using log normalization, but color limits pass through 0. "
|
|
483
|
+
"Adjusting so plotting doesn't fail"
|
|
484
|
+
)
|
|
485
|
+
|
|
486
|
+
# Filling in masked values must take place after automatic color limits
|
|
487
|
+
# might be calculated!
|
|
488
|
+
|
|
489
|
+
# This masking replicates the behavior of HealpixSkyMap, but is it
|
|
490
|
+
# what we really want to do? Why not use the default handling of
|
|
491
|
+
# masked values applied by skyproj?
|
|
492
|
+
if "mask_below" in self.plot_dict and self.plot_dict["mask_below"] is not None:
|
|
493
|
+
to_mask = np.where(hpix_map <= self.plot_dict["mask_below"])[0]
|
|
494
|
+
hpix_map.mask[to_mask] = True
|
|
495
|
+
hpix_map = hpix_map.filled(hp.UNSEEN)
|
|
496
|
+
else:
|
|
497
|
+
hpix_map = hpix_map.filled(slicer.badval)
|
|
498
|
+
|
|
499
|
+
self.skyproj.draw_hpxmap(hpix_map, **kwargs)
|
|
500
|
+
|
|
501
|
+
|
|
502
|
+
class VisitPerimeterPlotter(SkyprojPlotter):
|
|
503
|
+
default_visits_kwargs = {
|
|
504
|
+
"edgecolor": "black",
|
|
505
|
+
"linewidth": 0.2,
|
|
506
|
+
}
|
|
507
|
+
|
|
508
|
+
def __init__(self):
|
|
509
|
+
super().__init__()
|
|
510
|
+
self.plot_type = "SkyprojVisitPerimeter"
|
|
511
|
+
self.object_plotter = True
|
|
512
|
+
|
|
513
|
+
def draw(self, metric_values, slicer):
|
|
514
|
+
"""Draw the perimeters of visits.
|
|
515
|
+
|
|
516
|
+
Parameters
|
|
517
|
+
----------
|
|
518
|
+
metric_value : `numpy.ma.MaskedArray`
|
|
519
|
+
The metric values from the bundle.
|
|
520
|
+
slicer : `rubin_sim.maf.slicers.TwoDSlicer`
|
|
521
|
+
The slicer
|
|
522
|
+
"""
|
|
523
|
+
|
|
524
|
+
# If there are no visits, just return
|
|
525
|
+
if metric_values is None or len(metric_values) == 0:
|
|
526
|
+
return
|
|
527
|
+
|
|
528
|
+
kwargs = {}
|
|
529
|
+
kwargs.update(self.default_visits_kwargs)
|
|
530
|
+
|
|
531
|
+
visits = metric_values[0]
|
|
532
|
+
|
|
533
|
+
if "draw_polygon_kwargs" in self.plot_dict:
|
|
534
|
+
kwargs.update(self.plot_dict["draw_polygon_kwargs"])
|
|
535
|
+
|
|
536
|
+
camera_perimeter_func = self.plot_dict["camera_perimeter_func"]
|
|
537
|
+
|
|
538
|
+
ras, decls = camera_perimeter_func(visits["fieldRA"], visits["fieldDec"], visits["rotSkyPos"])
|
|
539
|
+
for visit_ras, visit_decls in zip(ras, decls):
|
|
540
|
+
self.skyproj.draw_polygon(visit_ras, visit_decls, **kwargs)
|