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,441 @@
|
|
|
1
|
+
__all__ = ("PrestoColorKNePopMetric", "generate_presto_pop_slicer")
|
|
2
|
+
|
|
3
|
+
import os
|
|
4
|
+
import pickle
|
|
5
|
+
import warnings
|
|
6
|
+
from itertools import combinations
|
|
7
|
+
|
|
8
|
+
import numpy as np
|
|
9
|
+
import pandas as pd
|
|
10
|
+
from rubin_scheduler.data import get_data_dir
|
|
11
|
+
from rubin_scheduler.utils import SURVEY_START_MJD, uniform_sphere
|
|
12
|
+
|
|
13
|
+
import rubin_sim.maf.metrics as metrics
|
|
14
|
+
import rubin_sim.maf.slicers as slicers
|
|
15
|
+
from rubin_sim.phot_utils import DustValues
|
|
16
|
+
|
|
17
|
+
from .kne_metrics import KnLc
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
def radec2gal(ra, dec):
|
|
21
|
+
"""convert from ra/dec to galactic l/b"""
|
|
22
|
+
from astropy import units as u
|
|
23
|
+
from astropy.coordinates import SkyCoord
|
|
24
|
+
|
|
25
|
+
c = SkyCoord(ra=ra, dec=dec, unit=(u.degree, u.degree))
|
|
26
|
+
|
|
27
|
+
gal_l = c.galactic.l.degree
|
|
28
|
+
gal_b = c.galactic.b.degree
|
|
29
|
+
return gal_l, gal_b
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
def _load_hash(
|
|
33
|
+
file_galactic="TotalCubeNorm_1000Obj.pkl",
|
|
34
|
+
file_extragalactic="TotalCubeNorm_1000Obj.pkl",
|
|
35
|
+
skyregion="extragalactic",
|
|
36
|
+
):
|
|
37
|
+
"""Helper function to load large hash table.
|
|
38
|
+
|
|
39
|
+
Because this is kept outside the metric attributes, it allows easy resuse.
|
|
40
|
+
Note that this does mean running different sky regions at the same
|
|
41
|
+
time may end up thrashing the data in the hash/hash table.
|
|
42
|
+
|
|
43
|
+
Parameters
|
|
44
|
+
----------
|
|
45
|
+
skyregion : `str`
|
|
46
|
+
The skyregion of interst.
|
|
47
|
+
Only two options: 'galactic' and 'extragalactic'
|
|
48
|
+
filePathGalactic : `str`
|
|
49
|
+
File containing galactic Presto-Color phase space information
|
|
50
|
+
filePathExtragalactic : `str`
|
|
51
|
+
File containing galactic Presto-Color phase space information
|
|
52
|
+
"""
|
|
53
|
+
|
|
54
|
+
if hasattr(_load_hash, "InfoDict"):
|
|
55
|
+
if skyregion == _load_hash.skyregion:
|
|
56
|
+
return _load_hash.InfoDict, _load_hash.HashTable
|
|
57
|
+
|
|
58
|
+
data_dir = get_data_dir()
|
|
59
|
+
if skyregion == "galactic":
|
|
60
|
+
file_path = os.path.join(data_dir, "maf", file_galactic)
|
|
61
|
+
elif skyregion == "extragalactic":
|
|
62
|
+
file_path = os.path.join(data_dir, "maf", file_extragalactic)
|
|
63
|
+
|
|
64
|
+
with open(file_path, "rb") as f:
|
|
65
|
+
_load_hash.InfoDict = pickle.load(f)
|
|
66
|
+
_load_hash.HashTable = pickle.load(f)
|
|
67
|
+
_load_hash.skyregion = skyregion
|
|
68
|
+
return _load_hash.InfoDict, _load_hash.HashTable
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
def generate_presto_pop_slicer(
|
|
72
|
+
skyregion="galactic",
|
|
73
|
+
t_start=1,
|
|
74
|
+
t_end=3652,
|
|
75
|
+
n_events=10000,
|
|
76
|
+
seed=42,
|
|
77
|
+
n_files=100,
|
|
78
|
+
d_min=10,
|
|
79
|
+
d_max=300,
|
|
80
|
+
gb_cut=20,
|
|
81
|
+
):
|
|
82
|
+
"""Generate a population of KNe events, and put the info about them
|
|
83
|
+
into a UserPointSlicer object
|
|
84
|
+
|
|
85
|
+
Parameters
|
|
86
|
+
----------
|
|
87
|
+
skyregion : `str`
|
|
88
|
+
The skyregion of interest.
|
|
89
|
+
Only two options: 'galactic' and 'extragalactic'
|
|
90
|
+
t_start : `float`
|
|
91
|
+
The night to start kilonova events on (days)
|
|
92
|
+
t_end : `float`
|
|
93
|
+
The final night of kilonova events
|
|
94
|
+
n_events : `int`
|
|
95
|
+
The number of kilonova events to generate
|
|
96
|
+
seed : `float`
|
|
97
|
+
The seed passed to np.random
|
|
98
|
+
n_files : `int`
|
|
99
|
+
The number of different kilonova lightcurves to use
|
|
100
|
+
d_min : `float` or `int`
|
|
101
|
+
Minimum luminosity distance (Mpc)
|
|
102
|
+
d_max : `float` or `int`
|
|
103
|
+
Maximum luminosity distance (Mpc)
|
|
104
|
+
|
|
105
|
+
Returns
|
|
106
|
+
-------
|
|
107
|
+
kne_slicer : `~.maf.UserPointsSlicer`
|
|
108
|
+
"""
|
|
109
|
+
|
|
110
|
+
def rndm(a, b, g, size=1):
|
|
111
|
+
"""Power-law gen for pdf(x) proportional to x^{g-1} for a<=x<=b"""
|
|
112
|
+
r = np.random.random(size=size)
|
|
113
|
+
ag, bg = a**g, b**g
|
|
114
|
+
return (ag + (bg - ag) * r) ** (1.0 / g)
|
|
115
|
+
|
|
116
|
+
ra, dec = uniform_sphere(n_events, seed=seed)
|
|
117
|
+
|
|
118
|
+
# Convert ra, dec to gl, gb
|
|
119
|
+
gl, gb = radec2gal(ra, dec)
|
|
120
|
+
|
|
121
|
+
# Determine if the object is in the Galaxy plane
|
|
122
|
+
if skyregion == "galactic": # keep the galactic events
|
|
123
|
+
ra = ra[np.abs(gb) < gb_cut]
|
|
124
|
+
dec = dec[np.abs(gb) < gb_cut]
|
|
125
|
+
elif skyregion == "extragalactic": # keep the extragalactic events.
|
|
126
|
+
ra = ra[np.abs(gb) > gb_cut]
|
|
127
|
+
dec = dec[np.abs(gb) > gb_cut]
|
|
128
|
+
else:
|
|
129
|
+
warnings.warn("Skyregion %s not recognized, using whole sky" % skyregion)
|
|
130
|
+
|
|
131
|
+
n_events = len(ra)
|
|
132
|
+
|
|
133
|
+
peak_times = np.random.uniform(low=t_start, high=t_end, size=n_events)
|
|
134
|
+
file_indx = np.floor(np.random.uniform(low=0, high=n_files, size=n_events)).astype(int)
|
|
135
|
+
|
|
136
|
+
# Define the distance
|
|
137
|
+
distance = rndm(d_min, d_max, 4, size=n_events)
|
|
138
|
+
|
|
139
|
+
# Set up the slicer to evaluate the catalog we just made
|
|
140
|
+
slicer = slicers.UserPointsSlicer(ra, dec, lat_lon_deg=True, badval=0)
|
|
141
|
+
# Add any additional information about each object to the slicer
|
|
142
|
+
slicer.slice_points["peak_time"] = peak_times
|
|
143
|
+
slicer.slice_points["file_indx"] = file_indx
|
|
144
|
+
slicer.slice_points["distance"] = distance
|
|
145
|
+
return slicer
|
|
146
|
+
|
|
147
|
+
|
|
148
|
+
class PrestoColorKNePopMetric(metrics.BaseMetric):
|
|
149
|
+
def __init__(
|
|
150
|
+
self,
|
|
151
|
+
metric_name="KNePopMetric",
|
|
152
|
+
mjd_col="observationStartMJD",
|
|
153
|
+
m5_col="fiveSigmaDepth",
|
|
154
|
+
filter_col="band",
|
|
155
|
+
night_col="night",
|
|
156
|
+
pts_needed=2,
|
|
157
|
+
file_list=None,
|
|
158
|
+
mjd0=SURVEY_START_MJD,
|
|
159
|
+
output_lc=False,
|
|
160
|
+
skyregion="galactic",
|
|
161
|
+
thr=0.003,
|
|
162
|
+
**kwargs,
|
|
163
|
+
):
|
|
164
|
+
"""
|
|
165
|
+
Parameters
|
|
166
|
+
----------
|
|
167
|
+
file_list : `str` or None, optional
|
|
168
|
+
File containing input lightcurves
|
|
169
|
+
mjd0 : `float`, optional
|
|
170
|
+
MJD of the start of the survey.
|
|
171
|
+
output_lc : `bool`, optional
|
|
172
|
+
Flag to whether or not to output lightcurve for each object.
|
|
173
|
+
skyregion : `str`, optional
|
|
174
|
+
The skyregion of interest.
|
|
175
|
+
Only two options: 'galactic' and 'extragalactic'
|
|
176
|
+
thr : `float`, optional
|
|
177
|
+
Threshold for "classification" of events via the Score_S
|
|
178
|
+
"""
|
|
179
|
+
maps = ["DustMap"]
|
|
180
|
+
self.mjd_col = mjd_col
|
|
181
|
+
self.m5_col = m5_col
|
|
182
|
+
self.filter_col = filter_col
|
|
183
|
+
self.night_col = night_col
|
|
184
|
+
# Boolean variable, if True the light curve will be exported
|
|
185
|
+
self.output_lc = output_lc
|
|
186
|
+
self.thr = thr
|
|
187
|
+
self.skyregion = skyregion
|
|
188
|
+
# read in file as light curve object;
|
|
189
|
+
self.lightcurves = KnLc(file_list=file_list)
|
|
190
|
+
|
|
191
|
+
self.mjd0 = mjd0
|
|
192
|
+
|
|
193
|
+
dust_properties = DustValues()
|
|
194
|
+
self.ax1 = dust_properties.ax1
|
|
195
|
+
|
|
196
|
+
cols = [self.mjd_col, self.m5_col, self.filter_col, self.night_col]
|
|
197
|
+
super().__init__(col=cols, units="Detected, 0 or 1", metric_name=metric_name, maps=maps, **kwargs)
|
|
198
|
+
|
|
199
|
+
# Unused ..
|
|
200
|
+
self.pts_needed = pts_needed
|
|
201
|
+
|
|
202
|
+
def _presto_color_detect(self, around_peak, filters):
|
|
203
|
+
"""Detection criteria of presto cadence:
|
|
204
|
+
at least three detections at two filters;
|
|
205
|
+
|
|
206
|
+
Parameters
|
|
207
|
+
----------
|
|
208
|
+
around_peak : `np.ndarray`, (N,)
|
|
209
|
+
indexes corresponding to 5sigma detections
|
|
210
|
+
filters : `np.ndarray`, (N,)
|
|
211
|
+
filters in which detections happened
|
|
212
|
+
"""
|
|
213
|
+
result = 1
|
|
214
|
+
|
|
215
|
+
if np.size(around_peak) < 3:
|
|
216
|
+
result = 0
|
|
217
|
+
|
|
218
|
+
flts, flts_count = np.unique(
|
|
219
|
+
filters,
|
|
220
|
+
return_counts=True,
|
|
221
|
+
)
|
|
222
|
+
if np.size(flts) < 2:
|
|
223
|
+
result = 0
|
|
224
|
+
elif np.max(flts_count) < 2:
|
|
225
|
+
# if no filters have visits larger than 2, set detection false
|
|
226
|
+
result = 0
|
|
227
|
+
|
|
228
|
+
return result
|
|
229
|
+
|
|
230
|
+
def _enquiry(self, hash_table, info_dict, band1, band2, d_t1, d_t2, d_mag, color):
|
|
231
|
+
"""
|
|
232
|
+
Return the value in the probability cube provided the coordinates
|
|
233
|
+
in the Presto-color phase space of an observation triplet.
|
|
234
|
+
|
|
235
|
+
Parameters
|
|
236
|
+
----------
|
|
237
|
+
hash_table : `np.ndarray`, (N,)
|
|
238
|
+
Contains the values of the 6-D Presto-color phase space
|
|
239
|
+
info_dict : `dict`
|
|
240
|
+
Contains the essential information of the hash_table abobe.
|
|
241
|
+
band1, band2 : `str`, `str`
|
|
242
|
+
The two filters that comprise the Presto-color observation triplet.
|
|
243
|
+
The filters are the 6 bands of LSST: u, g, r, i, z, y.
|
|
244
|
+
Band1 and band2 should be different.
|
|
245
|
+
d_t1, d_t2 : `float`, `float`
|
|
246
|
+
The time gaps of the Presto-color observation triplet.
|
|
247
|
+
d_mag : `float`
|
|
248
|
+
The magnitude change between from the observations of the same band
|
|
249
|
+
color : `float`
|
|
250
|
+
The difference in magnitude of observations in different bands.
|
|
251
|
+
|
|
252
|
+
hash_table and info_dict have to be loaded from premade data
|
|
253
|
+
Presto-color data file.
|
|
254
|
+
"""
|
|
255
|
+
|
|
256
|
+
# if abs(d_t1) > abs(d_t1-d_t2):
|
|
257
|
+
# d_t1, d_t2 = d_t1-d_t2, -d_t2
|
|
258
|
+
|
|
259
|
+
if not (
|
|
260
|
+
info_dict["BinMag"][0] <= d_mag < info_dict["BinMag"][-1]
|
|
261
|
+
and info_dict["BinColor"][0] <= color < info_dict["BinColor"][-1]
|
|
262
|
+
):
|
|
263
|
+
return 0
|
|
264
|
+
|
|
265
|
+
ind1 = info_dict["BandPairs"].index(band1 + band2)
|
|
266
|
+
|
|
267
|
+
time_pair_grid = [
|
|
268
|
+
info_dict["dT1s"][abs(d_t1 - info_dict["dT1s"]).argmin()],
|
|
269
|
+
info_dict["dT2s"][abs(d_t2 - info_dict["dT2s"]).argmin()],
|
|
270
|
+
]
|
|
271
|
+
|
|
272
|
+
ind2 = np.where((info_dict["TimePairs"] == time_pair_grid).all(axis=1))[0][0]
|
|
273
|
+
ind3 = np.where(d_mag >= info_dict["BinMag"])[0][-1]
|
|
274
|
+
ind4 = np.where(color >= info_dict["BinColor"])[0][-1]
|
|
275
|
+
|
|
276
|
+
return hash_table[ind1, ind2, ind3, ind4]
|
|
277
|
+
|
|
278
|
+
def _get_score(self, result, hash_table, info_dict, thr):
|
|
279
|
+
"""Get the score of a strategy from the Presto-color perspective.
|
|
280
|
+
|
|
281
|
+
Parameters
|
|
282
|
+
----------
|
|
283
|
+
result : `pd.DataFrame`
|
|
284
|
+
Dataframe that contains the results of the observations.
|
|
285
|
+
The columns include
|
|
286
|
+
t: the time of the observation
|
|
287
|
+
mag: the detected magnitude
|
|
288
|
+
maglim: the limit fiveSigmaDepth that can be detected
|
|
289
|
+
filter: the filter used for the observation
|
|
290
|
+
hash_table : `np.ndarray`, (N,)
|
|
291
|
+
Contains the values of the 6-D Presto-color phase space
|
|
292
|
+
info_dict : `dict`
|
|
293
|
+
Contains the essential information of the hash_table abobe.
|
|
294
|
+
scoreType : `str`
|
|
295
|
+
Two types of scores were designed:
|
|
296
|
+
'S' type involves a threshold,
|
|
297
|
+
'P' type work without a threshold.
|
|
298
|
+
thr : `float`
|
|
299
|
+
The threashold need for type 'S' score.
|
|
300
|
+
The default value is 0.003 (3-sigma)
|
|
301
|
+
|
|
302
|
+
hash_table and info_dict have to be loaded from the premade
|
|
303
|
+
Presto-color data file.
|
|
304
|
+
"""
|
|
305
|
+
|
|
306
|
+
time_lim1 = 8.125 / 24 # 8 h 7.5 min
|
|
307
|
+
time_lim2 = 32.25 / 24 # 32 h 15 min
|
|
308
|
+
|
|
309
|
+
detects = result[result.mag < result.maglim]
|
|
310
|
+
|
|
311
|
+
# reset index
|
|
312
|
+
detects = detects.reset_index(drop=True)
|
|
313
|
+
|
|
314
|
+
# Times for valid detections
|
|
315
|
+
ts = detects.t.values
|
|
316
|
+
# Find out the differences between each pair
|
|
317
|
+
d_ts = ts.reshape(1, len(ts)) - ts.reshape(len(ts), 1)
|
|
318
|
+
|
|
319
|
+
# The time differences should be within 32 hours (2 nights)
|
|
320
|
+
d_tindex0, d_tindex1 = np.where(abs(d_ts) < time_lim2)
|
|
321
|
+
|
|
322
|
+
phase_space_coords = []
|
|
323
|
+
|
|
324
|
+
# loop through the rows of the matrix of valid time differences
|
|
325
|
+
for ii in range(d_ts.shape[0]):
|
|
326
|
+
groups_of_three = np.array(
|
|
327
|
+
[
|
|
328
|
+
[ii] + list(jj)
|
|
329
|
+
for jj in list(combinations(d_tindex1[(d_tindex0 == ii) * (d_tindex1 > ii)], 2))
|
|
330
|
+
]
|
|
331
|
+
)
|
|
332
|
+
|
|
333
|
+
for indices in groups_of_three:
|
|
334
|
+
bands = detects["filter"][indices].values
|
|
335
|
+
|
|
336
|
+
# print('bands: ', bands)
|
|
337
|
+
if len(np.unique(bands)) != 2:
|
|
338
|
+
continue
|
|
339
|
+
|
|
340
|
+
# The band appears once will be band2
|
|
341
|
+
occurence = np.array([np.count_nonzero(ii == bands) for ii in bands])
|
|
342
|
+
# The index of observation in band2
|
|
343
|
+
index2 = indices[occurence == 1][0]
|
|
344
|
+
# The index of the first observation in band1
|
|
345
|
+
index11 = indices[occurence == 2][0]
|
|
346
|
+
# The index of the second observation in band1
|
|
347
|
+
index12 = indices[occurence == 2][1]
|
|
348
|
+
|
|
349
|
+
if (
|
|
350
|
+
abs(d_ts[index12, index2]) < abs(d_ts[index11, index2])
|
|
351
|
+
and abs(d_ts[index12, index2]) < time_lim1
|
|
352
|
+
):
|
|
353
|
+
index11, index12 = index12, index11
|
|
354
|
+
elif abs(d_ts[index11, index2]) > time_lim1:
|
|
355
|
+
continue
|
|
356
|
+
|
|
357
|
+
d_t1 = d_ts[index11, index2]
|
|
358
|
+
d_t2 = d_ts[index11, index12]
|
|
359
|
+
|
|
360
|
+
band1 = bands[occurence == 2][0]
|
|
361
|
+
band2 = bands[occurence == 1][0]
|
|
362
|
+
|
|
363
|
+
if band1 + band2 == "uy" or band1 + band2 == "yu":
|
|
364
|
+
continue
|
|
365
|
+
|
|
366
|
+
d_mag = (detects.mag[index11] - detects.mag[index12]) * np.sign(d_t2)
|
|
367
|
+
color = detects.mag[index11] - detects.mag[index2]
|
|
368
|
+
|
|
369
|
+
phase_space_coords.append([band1, band2, d_t1, d_t2, d_mag, color])
|
|
370
|
+
|
|
371
|
+
score_s = 0
|
|
372
|
+
score_p = [0]
|
|
373
|
+
|
|
374
|
+
for phase_space_coord in phase_space_coords:
|
|
375
|
+
rate = self._enquiry(hash_table, info_dict, *phase_space_coord)
|
|
376
|
+
|
|
377
|
+
if score_s == 0 and rate < thr:
|
|
378
|
+
score_s = 1
|
|
379
|
+
|
|
380
|
+
score_p.append((1 - rate))
|
|
381
|
+
|
|
382
|
+
return score_s, max(score_p)
|
|
383
|
+
|
|
384
|
+
def run(self, data_slice, slice_point=None):
|
|
385
|
+
data_slice.sort(order=self.mjd_col)
|
|
386
|
+
result = {}
|
|
387
|
+
t = data_slice[self.mjd_col] - self.mjd0 - slice_point["peak_time"]
|
|
388
|
+
mags = np.zeros(t.size, dtype=float)
|
|
389
|
+
|
|
390
|
+
for filtername in np.unique(data_slice[self.filter_col]):
|
|
391
|
+
infilt = np.where(data_slice[self.filter_col] == filtername)
|
|
392
|
+
mags[infilt] = self.lightcurves.interp(t[infilt], filtername, lc_indx=slice_point["file_indx"])
|
|
393
|
+
# Apply dust extinction on the light curve
|
|
394
|
+
a_x = self.ax1[filtername] * slice_point["ebv"]
|
|
395
|
+
mags[infilt] += a_x
|
|
396
|
+
|
|
397
|
+
distmod = 5 * np.log10(slice_point["distance"] * 1e6) - 5.0
|
|
398
|
+
mags[infilt] += distmod
|
|
399
|
+
|
|
400
|
+
# Find the detected points
|
|
401
|
+
around_peak = np.where((t > 0) & (t < 30) & (mags < data_slice[self.m5_col]))[0]
|
|
402
|
+
# Filters in which the detections happened
|
|
403
|
+
filters = data_slice[self.filter_col][around_peak]
|
|
404
|
+
|
|
405
|
+
# presto color
|
|
406
|
+
result["presto_color_detect"] = self._presto_color_detect(around_peak, filters)
|
|
407
|
+
|
|
408
|
+
# Export the light curve
|
|
409
|
+
idx = np.where(mags < 100)[0]
|
|
410
|
+
lc = {
|
|
411
|
+
"t": data_slice[self.mjd_col][idx],
|
|
412
|
+
"mag": mags[idx],
|
|
413
|
+
"maglim": data_slice[self.m5_col][idx],
|
|
414
|
+
"filter": data_slice[self.filter_col][idx],
|
|
415
|
+
}
|
|
416
|
+
|
|
417
|
+
if self.output_lc is True:
|
|
418
|
+
result["lc"] = lc
|
|
419
|
+
result["slice_point"] = slice_point
|
|
420
|
+
|
|
421
|
+
if result["presto_color_detect"] == 1:
|
|
422
|
+
info_dict, hash_table = _load_hash(skyregion=self.skyregion)
|
|
423
|
+
result["scoreS"], result["scoreP"] = self._get_score(
|
|
424
|
+
pd.DataFrame(lc),
|
|
425
|
+
hash_table=hash_table,
|
|
426
|
+
info_dict=info_dict,
|
|
427
|
+
thr=self.thr,
|
|
428
|
+
)
|
|
429
|
+
else:
|
|
430
|
+
result["scoreS"] = 0
|
|
431
|
+
result["scoreP"] = 0
|
|
432
|
+
return result
|
|
433
|
+
|
|
434
|
+
def reduce_presto_color_detect(self, metric):
|
|
435
|
+
return metric["presto_color_detect"]
|
|
436
|
+
|
|
437
|
+
def reduce_score_s(self, metric):
|
|
438
|
+
return metric["scoreS"]
|
|
439
|
+
|
|
440
|
+
def reduce_score_p(self, metric):
|
|
441
|
+
return metric["scoreP"]
|
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
__all__ = ("PhotometricSelfCalUniformityMetric",)
|
|
2
|
+
|
|
3
|
+
import os
|
|
4
|
+
import time
|
|
5
|
+
|
|
6
|
+
import healpy as hp
|
|
7
|
+
import numpy as np
|
|
8
|
+
from astropy.coordinates import SkyCoord
|
|
9
|
+
from astropy.table import Table
|
|
10
|
+
from rubin_scheduler.data import get_data_dir
|
|
11
|
+
from rubin_scheduler.utils import healbin
|
|
12
|
+
from scipy.stats import median_abs_deviation
|
|
13
|
+
|
|
14
|
+
from rubin_sim.maf.metrics import BaseMetric
|
|
15
|
+
from rubin_sim.selfcal import LsqrSolver, OffsetSNR, generate_catalog
|
|
16
|
+
from rubin_sim.selfcal.offsets import OffsetSys
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
def _match(arr1, arr2):
|
|
20
|
+
st1 = np.argsort(arr1)
|
|
21
|
+
sub1 = np.searchsorted(arr1, arr2, sorter=st1)
|
|
22
|
+
if arr2.max() > arr1.max():
|
|
23
|
+
bad = sub1 == arr1.size
|
|
24
|
+
sub1[bad] = arr1.size - 1
|
|
25
|
+
|
|
26
|
+
(sub2,) = np.where(arr1[st1[sub1]] == arr2)
|
|
27
|
+
sub1 = st1[sub1[sub2]]
|
|
28
|
+
|
|
29
|
+
return sub1, sub2
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
class PhotometricSelfCalUniformityMetric(BaseMetric):
|
|
33
|
+
def __init__(
|
|
34
|
+
self,
|
|
35
|
+
nside_residual=128,
|
|
36
|
+
highglat_cut=30.0,
|
|
37
|
+
outlier_nsig=4.0,
|
|
38
|
+
metric_name="PhotometricSelfCalUniformityMetric",
|
|
39
|
+
filter_name="r",
|
|
40
|
+
):
|
|
41
|
+
cols = [
|
|
42
|
+
"observationid",
|
|
43
|
+
"fieldra",
|
|
44
|
+
"fielddec",
|
|
45
|
+
"fiveSigmaDepth",
|
|
46
|
+
"rotSkyPos",
|
|
47
|
+
"filter",
|
|
48
|
+
]
|
|
49
|
+
super().__init__(col=cols, metric_name=metric_name)
|
|
50
|
+
|
|
51
|
+
filename = os.path.join(get_data_dir(), "maf", "monster_stars_uniformity_i15-18_sampled.parquet")
|
|
52
|
+
self.stars = Table.read(filename)
|
|
53
|
+
|
|
54
|
+
# We have to rename dec to decl for the selfcal code.
|
|
55
|
+
if "dec" in self.stars.dtype.names:
|
|
56
|
+
self.stars["decl"] = self.stars["dec"]
|
|
57
|
+
|
|
58
|
+
self.stars = self.stars.as_array()
|
|
59
|
+
|
|
60
|
+
self.nside_residual = nside_residual
|
|
61
|
+
self.highglat_cut = highglat_cut
|
|
62
|
+
self.outlier_nsig = outlier_nsig
|
|
63
|
+
|
|
64
|
+
self.units = "mmag"
|
|
65
|
+
self.filter_name = filter_name
|
|
66
|
+
|
|
67
|
+
def run(self, data_slice, slice_point=None):
|
|
68
|
+
offsets = [OffsetSys(error_sys=0.03), OffsetSNR(lsst_filter=self.filter_name)]
|
|
69
|
+
|
|
70
|
+
visits = np.zeros(
|
|
71
|
+
len(data_slice),
|
|
72
|
+
dtype=[
|
|
73
|
+
("observationId", "i8"),
|
|
74
|
+
("ra", "f8"),
|
|
75
|
+
("dec", "f8"),
|
|
76
|
+
("fiveSigmaDepth", "f8"),
|
|
77
|
+
("rotSkyPos", "f8"),
|
|
78
|
+
],
|
|
79
|
+
)
|
|
80
|
+
visits["observationId"] = data_slice["observationId"]
|
|
81
|
+
visits["ra"] = data_slice["fieldRA"]
|
|
82
|
+
visits["dec"] = data_slice["fieldDec"]
|
|
83
|
+
visits["fiveSigmaDepth"] = data_slice["fiveSigmaDepth"]
|
|
84
|
+
visits["rotSkyPos"] = data_slice["rotSkyPos"]
|
|
85
|
+
|
|
86
|
+
good_stars = np.isfinite(self.stars[f"{self.filter_name}mag"])
|
|
87
|
+
stars = self.stars[good_stars]
|
|
88
|
+
|
|
89
|
+
observed_stars = generate_catalog(
|
|
90
|
+
visits,
|
|
91
|
+
stars,
|
|
92
|
+
offsets=offsets,
|
|
93
|
+
lsst_filter=self.filter_name,
|
|
94
|
+
n_patches=16,
|
|
95
|
+
verbose=False,
|
|
96
|
+
)
|
|
97
|
+
|
|
98
|
+
solver = LsqrSolver(observed_stars)
|
|
99
|
+
|
|
100
|
+
print("Starting solver...")
|
|
101
|
+
t0 = time.time()
|
|
102
|
+
|
|
103
|
+
solver.run()
|
|
104
|
+
fit_patches, fit_stars = solver.return_solution()
|
|
105
|
+
|
|
106
|
+
t1 = time.time()
|
|
107
|
+
dt = (t1 - t0) / 60.0
|
|
108
|
+
print("runtime= %.1f min" % dt)
|
|
109
|
+
|
|
110
|
+
# Trim stars to the ones with solutions.
|
|
111
|
+
a, b = _match(stars["id"], fit_stars["id"])
|
|
112
|
+
stars_trimmed = stars[a]
|
|
113
|
+
fit_stars_trimmed = fit_stars[b]
|
|
114
|
+
|
|
115
|
+
# Residuals after fit, removing floating zeropoint
|
|
116
|
+
resid = stars_trimmed[f"{self.filter_name}mag"] - fit_stars_trimmed["fit_mag"]
|
|
117
|
+
resid = resid - np.median(resid)
|
|
118
|
+
|
|
119
|
+
resid_map = healbin(
|
|
120
|
+
stars_trimmed["ra"],
|
|
121
|
+
stars_trimmed["dec"],
|
|
122
|
+
resid,
|
|
123
|
+
self.nside_residual,
|
|
124
|
+
reduce_func=np.median,
|
|
125
|
+
)
|
|
126
|
+
|
|
127
|
+
(ipring,) = np.where(resid_map > hp.UNSEEN)
|
|
128
|
+
|
|
129
|
+
scatter_full = median_abs_deviation(resid_map[ipring], scale="normal")
|
|
130
|
+
|
|
131
|
+
# Fraction of (4) sigma outliers.
|
|
132
|
+
highscat = np.abs(resid_map[ipring]) > self.outlier_nsig * scatter_full
|
|
133
|
+
outlier_frac_full = highscat.sum() / len(ipring)
|
|
134
|
+
|
|
135
|
+
# Cut to high latitude
|
|
136
|
+
ra, dec = hp.pix2ang(self.nside_residual, ipring, nest=False, lonlat=True)
|
|
137
|
+
coords = SkyCoord(ra, dec, frame="icrs", unit="deg")
|
|
138
|
+
b = coords.galactic.b.value
|
|
139
|
+
|
|
140
|
+
high_glat = np.abs(b) > self.highglat_cut
|
|
141
|
+
scatter_highglat = median_abs_deviation(resid_map[ipring[high_glat]], scale="normal")
|
|
142
|
+
|
|
143
|
+
# Fraction of (4) sigma outliers.
|
|
144
|
+
highscat = np.abs(resid_map[ipring[high_glat]]) > self.outlier_nsig * scatter_highglat
|
|
145
|
+
outlier_frac_highglat = highscat.sum() / len(ipring)
|
|
146
|
+
|
|
147
|
+
# Convert to mmag
|
|
148
|
+
scatter_full = scatter_full * 1000.0
|
|
149
|
+
scatter_highglat = scatter_highglat * 1000.0
|
|
150
|
+
|
|
151
|
+
result = {
|
|
152
|
+
"scatter_full": scatter_full,
|
|
153
|
+
"scatter_highglat": scatter_highglat,
|
|
154
|
+
"outlier_frac_full": outlier_frac_full,
|
|
155
|
+
"outlier_frac_highglat": outlier_frac_highglat,
|
|
156
|
+
"uniformity_map": resid_map,
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
return result
|
|
160
|
+
|
|
161
|
+
def reduce_scatter_full(self, metric_value):
|
|
162
|
+
return metric_value["scatter_full"]
|
|
163
|
+
|
|
164
|
+
def reduce_scatter_highglat(self, metric_value):
|
|
165
|
+
return metric_value["scatter_highglat"]
|
|
166
|
+
|
|
167
|
+
def reduce_outlier_frac_full(self, metric_value):
|
|
168
|
+
return metric_value["outlier_frac_full"]
|
|
169
|
+
|
|
170
|
+
def reduce_outlier_frac_highglat(self, metric_value):
|
|
171
|
+
return metric_value["outlier_frac_highglat"]
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
__all__ = ("StarCountMassMetric",)
|
|
2
|
+
|
|
3
|
+
import numpy as np
|
|
4
|
+
|
|
5
|
+
from rubin_sim.maf.metrics import BaseMetric
|
|
6
|
+
|
|
7
|
+
from .star_counts import starcount_bymass
|
|
8
|
+
|
|
9
|
+
# Example for CountMassMetric
|
|
10
|
+
# Mike Lund - Vanderbilt University
|
|
11
|
+
# mike.lund@gmail.com
|
|
12
|
+
# Last edited 8/15/2015
|
|
13
|
+
# Motivation: The distances to stars in LSST will be significant enough that
|
|
14
|
+
# the structure of the Galaxy will be readily apparent because of its
|
|
15
|
+
# influence on the number of stars in a given field.
|
|
16
|
+
# Any metric concerned with the number of potential objects to be detected
|
|
17
|
+
# will need to feature not only the effects of the cadence but also the
|
|
18
|
+
# number of objects per field.
|
|
19
|
+
# This metric identifies the number of stars in a given field in a particular
|
|
20
|
+
# mass range that will be fainter than the saturation limit of 16th magnitude
|
|
21
|
+
# and still bright enough to have noise less than 0.03 mag.
|
|
22
|
+
# M1 and M2 are the low and high limits of the mass range in solar masses.
|
|
23
|
+
# 'band' is the band for the observations to be made in.
|
|
24
|
+
# Requires StarCounts.StarCounts
|
|
25
|
+
|
|
26
|
+
# NOTE
|
|
27
|
+
# There are stellar luminosity function maps available within MAF
|
|
28
|
+
# that may supersede these StarCount functions
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
class StarCountMassMetric(BaseMetric):
|
|
32
|
+
"""Find the number of stars in a given field in the mass range
|
|
33
|
+
fainter than magnitude 16 and bright enough to have noise less than
|
|
34
|
+
0.03 in a given band.
|
|
35
|
+
M1 and m2 are the upper and lower limits of the mass range.
|
|
36
|
+
'band' is the band to be observed.
|
|
37
|
+
|
|
38
|
+
This metric uses the stellar distance and luminosity equations
|
|
39
|
+
contributed by Mike Lund, which are based on the Galfast model.
|
|
40
|
+
There are some imposed limitations on the expected magnitudes
|
|
41
|
+
of the stars included for the metric, based on assuming saturation
|
|
42
|
+
at 16th magnitude and not considering stars with magnitude
|
|
43
|
+
uncertainties greater than 0.03 (based on photometry/m5 alone).
|
|
44
|
+
|
|
45
|
+
Parameters
|
|
46
|
+
----------
|
|
47
|
+
m1 : `float`
|
|
48
|
+
Lower limit of the mass range.
|
|
49
|
+
m2 : `float`
|
|
50
|
+
Upper limit of the mass range.
|
|
51
|
+
band : `str`
|
|
52
|
+
Bandpass to consider.
|
|
53
|
+
"""
|
|
54
|
+
|
|
55
|
+
def __init__(self, m1=0.9, m2=1.0, band="i", **kwargs):
|
|
56
|
+
self.m1 = m1
|
|
57
|
+
self.m2 = m2
|
|
58
|
+
self.band = band
|
|
59
|
+
super(StarCountMassMetric, self).__init__(col=[], **kwargs)
|
|
60
|
+
|
|
61
|
+
def run(self, data_slice, slice_point=None):
|
|
62
|
+
self.dec_col = np.degrees(data_slice[0][3])
|
|
63
|
+
self.ra_col = np.degrees(data_slice[0][2])
|
|
64
|
+
return starcount_bymass.starcount_bymass(self.ra_col, self.dec_col, self.m1, self.m2, self.band)
|