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,473 @@
|
|
|
1
|
+
__all__ = ("get_kne_filename", "KnLc", "KNePopMetric", "generate_kn_pop_slicer")
|
|
2
|
+
|
|
3
|
+
import glob
|
|
4
|
+
import os
|
|
5
|
+
|
|
6
|
+
import numpy as np
|
|
7
|
+
from rubin_scheduler.data import get_data_dir
|
|
8
|
+
from rubin_scheduler.utils import SURVEY_START_MJD, uniform_sphere
|
|
9
|
+
|
|
10
|
+
from rubin_sim.maf.metrics import BaseMetric
|
|
11
|
+
from rubin_sim.maf.slicers import UserPointsSlicer
|
|
12
|
+
from rubin_sim.maf.utils import m52snr
|
|
13
|
+
from rubin_sim.phot_utils import DustValues
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
def get_kne_filename(inj_params_list=None):
|
|
17
|
+
"""Given kilonova parameters, get the filename from the grid of models
|
|
18
|
+
developed by M. Bulla
|
|
19
|
+
|
|
20
|
+
Parameters
|
|
21
|
+
----------
|
|
22
|
+
inj_params_list : `list` [`dict`]
|
|
23
|
+
parameters for the kilonova model such as
|
|
24
|
+
mass of the dynamical ejecta (mej_dyn), mass of the disk wind ejecta
|
|
25
|
+
(mej_wind), semi opening angle of the cylindrically-symmetric ejecta
|
|
26
|
+
fan ('phi'), and viewing angle ('theta'). For example
|
|
27
|
+
inj_params_list =
|
|
28
|
+
[{'mej_dyn': 0.005, 'mej_wind': 0.050, 'phi': 30, 'theta': 25.8}]
|
|
29
|
+
"""
|
|
30
|
+
# Get files, model grid developed by M. Bulla
|
|
31
|
+
datadir = get_data_dir()
|
|
32
|
+
file_list = glob.glob(os.path.join(datadir, "maf", "bns", "*.dat"))
|
|
33
|
+
|
|
34
|
+
# If no specific parameters passed - return everything.
|
|
35
|
+
if inj_params_list is None or len(inj_params_list) == 0:
|
|
36
|
+
return file_list
|
|
37
|
+
|
|
38
|
+
# Otherwise find the parameters for each file and
|
|
39
|
+
# then find the relevant matches.
|
|
40
|
+
params = {}
|
|
41
|
+
matched_files = []
|
|
42
|
+
for filename in file_list:
|
|
43
|
+
key = filename.replace(".dat", "").split("/")[-1]
|
|
44
|
+
params[key] = {}
|
|
45
|
+
params[key]["filename"] = filename
|
|
46
|
+
key_split = key.split("_")
|
|
47
|
+
# Binary neutron star merger models
|
|
48
|
+
if key_split[0] == "nsns":
|
|
49
|
+
mejdyn = float(key_split[2].replace("mejdyn", ""))
|
|
50
|
+
mejwind = float(key_split[3].replace("mejwind", ""))
|
|
51
|
+
phi0 = float(key_split[4].replace("phi", ""))
|
|
52
|
+
theta = float(key_split[5])
|
|
53
|
+
params[key]["mej_dyn"] = mejdyn
|
|
54
|
+
params[key]["mej_wind"] = mejwind
|
|
55
|
+
params[key]["phi"] = phi0
|
|
56
|
+
params[key]["theta"] = theta
|
|
57
|
+
# Neutron star--black hole merger models
|
|
58
|
+
elif key_split[0] == "nsbh":
|
|
59
|
+
mej_dyn = float(key_split[2].replace("mejdyn", ""))
|
|
60
|
+
mej_wind = float(key_split[3].replace("mejwind", ""))
|
|
61
|
+
phi = float(key_split[4].replace("phi", ""))
|
|
62
|
+
theta = float(key_split[5])
|
|
63
|
+
params[key]["mej_dyn"] = mej_dyn
|
|
64
|
+
params[key]["mej_wind"] = mej_wind
|
|
65
|
+
params[key]["phi"] = phi
|
|
66
|
+
params[key]["theta"] = theta
|
|
67
|
+
for key in params.keys():
|
|
68
|
+
for inj_params in inj_params_list:
|
|
69
|
+
match = all([np.isclose(params[key][var], inj_params[var]) for var in inj_params.keys()])
|
|
70
|
+
if match:
|
|
71
|
+
matched_files.append(params[key]["filename"])
|
|
72
|
+
print(f"Found match for {inj_params}")
|
|
73
|
+
print(
|
|
74
|
+
f"Found matches for {len(matched_files)}/{len(inj_params_list)} \
|
|
75
|
+
sets of parameters"
|
|
76
|
+
)
|
|
77
|
+
|
|
78
|
+
return matched_files
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
class KnLc:
|
|
82
|
+
"""Read in some KNe lightcurves
|
|
83
|
+
|
|
84
|
+
Parameters
|
|
85
|
+
----------
|
|
86
|
+
file_list : `list` [`str`] or None
|
|
87
|
+
List of file paths to load. If None, loads up all the files
|
|
88
|
+
from data/bns/
|
|
89
|
+
"""
|
|
90
|
+
|
|
91
|
+
def __init__(self, file_list=None):
|
|
92
|
+
if file_list is None:
|
|
93
|
+
datadir = get_data_dir()
|
|
94
|
+
# Get files, model grid developed by M. Bulla
|
|
95
|
+
file_list = glob.glob(os.path.join(datadir, "maf", "bns", "*.dat"))
|
|
96
|
+
|
|
97
|
+
filts = ["u", "g", "r", "i", "z", "y"]
|
|
98
|
+
magidxs = [1, 2, 3, 4, 5, 6]
|
|
99
|
+
|
|
100
|
+
# Let's organize the data in to a list of dicts for easy lookup
|
|
101
|
+
self.data = []
|
|
102
|
+
for filename in file_list:
|
|
103
|
+
mag_ds = np.loadtxt(filename)
|
|
104
|
+
t = mag_ds[:, 0]
|
|
105
|
+
new_dict = {}
|
|
106
|
+
for ii, (filt, magidx) in enumerate(zip(filts, magidxs)):
|
|
107
|
+
new_dict[filt] = {"ph": t, "mag": mag_ds[:, magidx]}
|
|
108
|
+
self.data.append(new_dict)
|
|
109
|
+
|
|
110
|
+
def interp(self, t, filtername, lc_indx=0):
|
|
111
|
+
"""Do the interpolation of the lightcurve for a given time and filter.
|
|
112
|
+
|
|
113
|
+
Parameters
|
|
114
|
+
----------
|
|
115
|
+
t : `np.ndarray`, (N,)
|
|
116
|
+
The times to interpolate the light curve to.
|
|
117
|
+
filtername : `str`
|
|
118
|
+
The filter. one of ugrizy
|
|
119
|
+
lc_index : `int`, optional
|
|
120
|
+
Which file to use.
|
|
121
|
+
|
|
122
|
+
Returns
|
|
123
|
+
-------
|
|
124
|
+
result : `np.ndarray`, (N,)
|
|
125
|
+
Array of lightcurve brightnesses at the times of t.=
|
|
126
|
+
"""
|
|
127
|
+
|
|
128
|
+
result = np.interp(
|
|
129
|
+
t,
|
|
130
|
+
self.data[lc_indx][filtername]["ph"],
|
|
131
|
+
self.data[lc_indx][filtername]["mag"],
|
|
132
|
+
left=99,
|
|
133
|
+
right=99,
|
|
134
|
+
)
|
|
135
|
+
return result
|
|
136
|
+
|
|
137
|
+
|
|
138
|
+
class KNePopMetric(BaseMetric):
|
|
139
|
+
def __init__(
|
|
140
|
+
self,
|
|
141
|
+
metric_name="KNePopMetric",
|
|
142
|
+
mjd_col="observationStartMJD",
|
|
143
|
+
m5_col="fiveSigmaDepth",
|
|
144
|
+
filter_col="band",
|
|
145
|
+
night_col="night",
|
|
146
|
+
pts_needed=2,
|
|
147
|
+
file_list=None,
|
|
148
|
+
mjd0=SURVEY_START_MJD,
|
|
149
|
+
output_lc=False,
|
|
150
|
+
badval=-666,
|
|
151
|
+
**kwargs,
|
|
152
|
+
):
|
|
153
|
+
maps = ["DustMap"]
|
|
154
|
+
self.mjd_col = mjd_col
|
|
155
|
+
self.m5_col = m5_col
|
|
156
|
+
self.filter_col = filter_col
|
|
157
|
+
self.night_col = night_col
|
|
158
|
+
self.pts_needed = pts_needed
|
|
159
|
+
# `bool` variable, if True the light curve will be exported
|
|
160
|
+
self.output_lc = output_lc
|
|
161
|
+
|
|
162
|
+
self.lightcurves = KnLc(file_list=file_list)
|
|
163
|
+
|
|
164
|
+
self.mjd0 = mjd0
|
|
165
|
+
|
|
166
|
+
dust_properties = DustValues()
|
|
167
|
+
self.ax1 = dust_properties.ax1
|
|
168
|
+
|
|
169
|
+
cols = [self.mjd_col, self.m5_col, self.filter_col, self.night_col]
|
|
170
|
+
super(KNePopMetric, self).__init__(
|
|
171
|
+
col=cols,
|
|
172
|
+
units="Detected, 0 or 1",
|
|
173
|
+
metric_name=metric_name,
|
|
174
|
+
maps=maps,
|
|
175
|
+
badval=badval,
|
|
176
|
+
**kwargs,
|
|
177
|
+
)
|
|
178
|
+
|
|
179
|
+
def _multi_detect(self, around_peak):
|
|
180
|
+
"""Simple detection criteria:
|
|
181
|
+
detect at least a certain number of times
|
|
182
|
+
"""
|
|
183
|
+
result = 1
|
|
184
|
+
# Detected data points
|
|
185
|
+
if np.size(around_peak) < self.pts_needed:
|
|
186
|
+
return 0
|
|
187
|
+
|
|
188
|
+
return result
|
|
189
|
+
|
|
190
|
+
def _ztfrest_simple(
|
|
191
|
+
self,
|
|
192
|
+
around_peak,
|
|
193
|
+
mags,
|
|
194
|
+
mags_unc,
|
|
195
|
+
t,
|
|
196
|
+
filters,
|
|
197
|
+
min_dt=0.125,
|
|
198
|
+
min_fade=0.3,
|
|
199
|
+
max_rise=-1.0,
|
|
200
|
+
select_red=False,
|
|
201
|
+
select_blue=False,
|
|
202
|
+
):
|
|
203
|
+
"""Selection criteria based on rise or decay rate;
|
|
204
|
+
simplified version of the methods employed by the ZTFReST project
|
|
205
|
+
(Andreoni & Coughlin et al., 2021)
|
|
206
|
+
|
|
207
|
+
Parameters
|
|
208
|
+
----------
|
|
209
|
+
around_peak : `np.ndarray`, (N,)
|
|
210
|
+
indexes corresponding to 5sigma detections
|
|
211
|
+
mags : `np.ndarray`, (N,)
|
|
212
|
+
magnitudes obtained interpolating models on the data_slice
|
|
213
|
+
t : `np.ndarray`, (N,)
|
|
214
|
+
relative times
|
|
215
|
+
filters : `np.ndarray`, (N,)
|
|
216
|
+
filters in which detections happened
|
|
217
|
+
min_dt : `float`
|
|
218
|
+
minimum time gap between first and last detection in a given band
|
|
219
|
+
min_fade : `float`
|
|
220
|
+
fade rate threshold (positive, mag/day)
|
|
221
|
+
max_rise : `float`
|
|
222
|
+
rise rate threshold (negative, mag/day)
|
|
223
|
+
select_red : `bool`
|
|
224
|
+
if True, only red 'izy' filters will be considered
|
|
225
|
+
select_blue : `bool`
|
|
226
|
+
if True, only blue 'ugr' filters will be considered
|
|
227
|
+
|
|
228
|
+
Examples
|
|
229
|
+
----------
|
|
230
|
+
A transient:
|
|
231
|
+
rising by 0.74 mag/day will pass a threshold max_rise=-0.5
|
|
232
|
+
rising by 0.74 mag/day will not pass a threshold max_rise=-1.0
|
|
233
|
+
fading by 0.6 mag/day will pass a threshold min_fade=0.3
|
|
234
|
+
fading by 0.2 mag/day will not pass a threshold min_fade=0.3
|
|
235
|
+
"""
|
|
236
|
+
result = 1
|
|
237
|
+
|
|
238
|
+
# Quick check on the number of detected points
|
|
239
|
+
if np.size(around_peak) < self.pts_needed:
|
|
240
|
+
return 0
|
|
241
|
+
# Quick check on the time gap between first and last detection
|
|
242
|
+
elif np.max(t[around_peak]) - np.min(t[around_peak]) < min_dt:
|
|
243
|
+
return 0
|
|
244
|
+
else:
|
|
245
|
+
evol_rate = []
|
|
246
|
+
fil = []
|
|
247
|
+
# Check time gaps and rise or fade rate for each band
|
|
248
|
+
for f in set(filters):
|
|
249
|
+
if select_red is True and f not in "izy":
|
|
250
|
+
continue
|
|
251
|
+
elif select_blue is True and f not in "ugr":
|
|
252
|
+
continue
|
|
253
|
+
times_f = t[around_peak][np.where(filters == f)[0]]
|
|
254
|
+
mags_f = mags[around_peak][np.where(filters == f)[0]]
|
|
255
|
+
mags_unc_f = mags_unc[around_peak][np.where(filters == f)[0]]
|
|
256
|
+
|
|
257
|
+
# Check if the evolution is significant enough
|
|
258
|
+
idx_max = np.argmax(mags_f)
|
|
259
|
+
idx_min = np.argmin(mags_f)
|
|
260
|
+
if mags_f[idx_min] + mags_unc_f[idx_min] < mags_f[idx_max] - mags_unc_f[idx_max]:
|
|
261
|
+
signif = True
|
|
262
|
+
else:
|
|
263
|
+
signif = False
|
|
264
|
+
|
|
265
|
+
# Time difference between max and min
|
|
266
|
+
dt_f = np.abs(times_f[idx_max] - times_f[idx_min])
|
|
267
|
+
|
|
268
|
+
# Get the evolution rate, if the time gap condition is met
|
|
269
|
+
if dt_f > min_dt and signif is True:
|
|
270
|
+
# Calculate evolution rate
|
|
271
|
+
evol_rate_f = (np.max(mags_f) - np.min(mags_f)) / (times_f[idx_max] - times_f[idx_min])
|
|
272
|
+
evol_rate.append(evol_rate_f)
|
|
273
|
+
else:
|
|
274
|
+
evol_rate.append(0)
|
|
275
|
+
fil.append(f)
|
|
276
|
+
if len(evol_rate) == 0:
|
|
277
|
+
return 0
|
|
278
|
+
# Check if the conditions on the evolution rate are met
|
|
279
|
+
if np.max(evol_rate) < min_fade and np.min(evol_rate) > max_rise:
|
|
280
|
+
return 0
|
|
281
|
+
|
|
282
|
+
return result
|
|
283
|
+
|
|
284
|
+
def _multi_color_detect(self, filters):
|
|
285
|
+
"""Color-based simple detection criteria:
|
|
286
|
+
detect at least twice, with at least two filters
|
|
287
|
+
"""
|
|
288
|
+
result = 1
|
|
289
|
+
# detected in at least two filters
|
|
290
|
+
if np.size(np.unique(filters)) < 2:
|
|
291
|
+
return 0
|
|
292
|
+
|
|
293
|
+
return result
|
|
294
|
+
|
|
295
|
+
def _red_color_detect(self, filters, min_det=4):
|
|
296
|
+
"""Detected at least min_det times in either izy colors
|
|
297
|
+
|
|
298
|
+
Parameters
|
|
299
|
+
----------
|
|
300
|
+
filters : `np.ndarray`, (N,)
|
|
301
|
+
filters in which detections happened
|
|
302
|
+
min_det : `float` or `int`
|
|
303
|
+
minimum number of detections required in izy bands
|
|
304
|
+
"""
|
|
305
|
+
result = 1
|
|
306
|
+
# Number of detected points in izy bands
|
|
307
|
+
n_red_det = (
|
|
308
|
+
np.size(np.where(filters == "i")[0])
|
|
309
|
+
+ np.size(np.where(filters == "z")[0])
|
|
310
|
+
+ np.size(np.where(filters == "y")[0])
|
|
311
|
+
)
|
|
312
|
+
# Condition
|
|
313
|
+
if n_red_det < min_det:
|
|
314
|
+
return 0
|
|
315
|
+
|
|
316
|
+
return result
|
|
317
|
+
|
|
318
|
+
def _blue_color_detect(self, filters, min_det=4):
|
|
319
|
+
"""Detected at least min_det times in either ugr colors
|
|
320
|
+
|
|
321
|
+
Parameters
|
|
322
|
+
----------
|
|
323
|
+
filters : `np.ndarray`, (N,)
|
|
324
|
+
filters in which detections happened
|
|
325
|
+
min_det : `float` or `int`
|
|
326
|
+
minimum number of detections required in ugr bands
|
|
327
|
+
"""
|
|
328
|
+
result = 1
|
|
329
|
+
# Number of detected points in ugr bands
|
|
330
|
+
n_blue_det = (
|
|
331
|
+
np.size(np.where(filters == "u")[0])
|
|
332
|
+
+ np.size(np.where(filters == "g")[0])
|
|
333
|
+
+ np.size(np.where(filters == "r")[0])
|
|
334
|
+
)
|
|
335
|
+
# Condition
|
|
336
|
+
if n_blue_det < min_det:
|
|
337
|
+
return 0
|
|
338
|
+
|
|
339
|
+
return result
|
|
340
|
+
|
|
341
|
+
def run(self, data_slice, slice_point=None):
|
|
342
|
+
result = {}
|
|
343
|
+
t = data_slice[self.mjd_col] - self.mjd0 - slice_point["peak_time"]
|
|
344
|
+
mags = np.zeros(t.size, dtype=float)
|
|
345
|
+
|
|
346
|
+
for filtername in np.unique(data_slice[self.filter_col]):
|
|
347
|
+
infilt = np.where(data_slice[self.filter_col] == filtername)
|
|
348
|
+
mags[infilt] = self.lightcurves.interp(t[infilt], filtername, lc_indx=slice_point["file_indx"])
|
|
349
|
+
# Apply dust extinction on the light curve
|
|
350
|
+
a_x = self.ax1[filtername] * slice_point["ebv"]
|
|
351
|
+
mags[infilt] += a_x
|
|
352
|
+
|
|
353
|
+
distmod = 5 * np.log10(slice_point["distance"] * 1e6) - 5.0
|
|
354
|
+
mags[infilt] += distmod
|
|
355
|
+
|
|
356
|
+
# Find the detected points
|
|
357
|
+
around_peak = np.where((t > 0) & (t < 30) & (mags < data_slice[self.m5_col]))[0]
|
|
358
|
+
# Filters in which the detections happened
|
|
359
|
+
filters = data_slice[self.filter_col][around_peak]
|
|
360
|
+
# Magnitude uncertainties with Gaussian approximation
|
|
361
|
+
snr = m52snr(mags, data_slice[self.m5_col])
|
|
362
|
+
mags_unc = 2.5 * np.log10(1.0 + 1.0 / snr)
|
|
363
|
+
|
|
364
|
+
result["multi_detect"] = self._multi_detect(around_peak)
|
|
365
|
+
result["ztfrest_simple"] = self._ztfrest_simple(
|
|
366
|
+
around_peak, mags, mags_unc, t, filters, select_red=False
|
|
367
|
+
)
|
|
368
|
+
result["ztfrest_simple_red"] = self._ztfrest_simple(
|
|
369
|
+
around_peak, mags, mags_unc, t, filters, select_red=True
|
|
370
|
+
)
|
|
371
|
+
result["ztfrest_simple_blue"] = self._ztfrest_simple(
|
|
372
|
+
around_peak, mags, mags_unc, t, filters, select_blue=True
|
|
373
|
+
)
|
|
374
|
+
result["multi_color_detect"] = self._multi_color_detect(filters)
|
|
375
|
+
result["red_color_detect"] = self._red_color_detect(filters)
|
|
376
|
+
result["blue_color_detect"] = self._blue_color_detect(filters)
|
|
377
|
+
|
|
378
|
+
# Export the light curve
|
|
379
|
+
if self.output_lc is True:
|
|
380
|
+
mags[np.where(mags > 50)[0]] = 99.0
|
|
381
|
+
result["lc"] = [
|
|
382
|
+
data_slice[self.mjd_col],
|
|
383
|
+
mags,
|
|
384
|
+
mags_unc,
|
|
385
|
+
data_slice[self.m5_col],
|
|
386
|
+
data_slice[self.filter_col],
|
|
387
|
+
]
|
|
388
|
+
result["lc_colnames"] = ("t", "mag", "mag_unc", "maglim", "filter")
|
|
389
|
+
|
|
390
|
+
return result
|
|
391
|
+
|
|
392
|
+
def reduce_multi_detect(self, metric):
|
|
393
|
+
return metric["multi_detect"]
|
|
394
|
+
|
|
395
|
+
def reduce_ztfrest_simple(self, metric):
|
|
396
|
+
return metric["ztfrest_simple"]
|
|
397
|
+
|
|
398
|
+
def reduce_ztfrest_simple_red(self, metric):
|
|
399
|
+
return metric["ztfrest_simple_red"]
|
|
400
|
+
|
|
401
|
+
def reduce_ztfrest_simple_blue(self, metric):
|
|
402
|
+
return metric["ztfrest_simple_blue"]
|
|
403
|
+
|
|
404
|
+
def reduce_multi_color_detect(self, metric):
|
|
405
|
+
return metric["multi_color_detect"]
|
|
406
|
+
|
|
407
|
+
def reduce_red_color_detect(self, metric):
|
|
408
|
+
return metric["red_color_detect"]
|
|
409
|
+
|
|
410
|
+
def reduce_blue_color_detect(self, metric):
|
|
411
|
+
return metric["blue_color_detect"]
|
|
412
|
+
|
|
413
|
+
|
|
414
|
+
def generate_kn_pop_slicer(
|
|
415
|
+
t_start=1,
|
|
416
|
+
t_end=3652,
|
|
417
|
+
n_events=10000,
|
|
418
|
+
seed=42,
|
|
419
|
+
n_files=308,
|
|
420
|
+
d_min=10,
|
|
421
|
+
d_max=300,
|
|
422
|
+
ra=None,
|
|
423
|
+
dec=None,
|
|
424
|
+
):
|
|
425
|
+
"""Generate a population of KNe events, and put the info about them
|
|
426
|
+
into a UserPointSlicer object
|
|
427
|
+
|
|
428
|
+
Parameters
|
|
429
|
+
----------
|
|
430
|
+
t_start : `float`, optional
|
|
431
|
+
The night to start kilonova events on (days)
|
|
432
|
+
t_end : `float`, optional
|
|
433
|
+
The final night of kilonova events
|
|
434
|
+
n_events : `int`, optional
|
|
435
|
+
The number of kilonova events to generate
|
|
436
|
+
seed : `float`, optional
|
|
437
|
+
The seed passed to np.random
|
|
438
|
+
n_files : `int`, optional
|
|
439
|
+
The number of different kilonova lightcurves to use
|
|
440
|
+
This should match the length of the filenames list passed
|
|
441
|
+
to the KNePopMetric directly.
|
|
442
|
+
d_min : `float` or `int`, optional
|
|
443
|
+
Minimum luminosity distance (Mpc)
|
|
444
|
+
d_max : `float` or `int`, optional
|
|
445
|
+
Maximum luminosity distance (Mpc)
|
|
446
|
+
ra, dec : `np.ndarray`, (N,) or None
|
|
447
|
+
The ra and dec to use for event positions.
|
|
448
|
+
Generates uniformly on the spehere if None. (degrees)
|
|
449
|
+
"""
|
|
450
|
+
|
|
451
|
+
def rndm(a, b, g, size=1):
|
|
452
|
+
"""Power-law gen for pdf(x) propto x^{g-1} for a<=x<=b"""
|
|
453
|
+
r = np.random.random(size=size)
|
|
454
|
+
ag, bg = a**g, b**g
|
|
455
|
+
return (ag + (bg - ag) * r) ** (1.0 / g)
|
|
456
|
+
|
|
457
|
+
if ra is None:
|
|
458
|
+
ra, dec = uniform_sphere(n_events, seed=seed)
|
|
459
|
+
|
|
460
|
+
peak_times = np.random.uniform(low=t_start, high=t_end, size=n_events)
|
|
461
|
+
file_indx = np.floor(np.random.uniform(low=0, high=n_files, size=n_events)).astype(int)
|
|
462
|
+
|
|
463
|
+
# Define the distance
|
|
464
|
+
distance = rndm(d_min, d_max, 4, size=n_events)
|
|
465
|
+
|
|
466
|
+
# Set up the slicer to evaluate the catalog we just made
|
|
467
|
+
slicer = UserPointsSlicer(ra, dec, lat_lon_deg=True, badval=0)
|
|
468
|
+
# Add any additional information about each object to the slicer
|
|
469
|
+
slicer.slice_points["peak_time"] = peak_times
|
|
470
|
+
slicer.slice_points["file_indx"] = file_indx
|
|
471
|
+
slicer.slice_points["distance"] = distance
|
|
472
|
+
|
|
473
|
+
return slicer
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
__all__ = ("GalaxyCountsMetric",)
|
|
2
|
+
|
|
3
|
+
import healpy as hp
|
|
4
|
+
import numpy as np
|
|
5
|
+
import scipy
|
|
6
|
+
|
|
7
|
+
from rubin_sim.maf.metrics.base_metric import BaseMetric
|
|
8
|
+
from rubin_sim.maf.metrics.exgal_m5 import ExgalM5
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class GalaxyCountsMetric(BaseMetric):
|
|
12
|
+
"""Estimate the number of galaxies expected at a particular (extragalactic)
|
|
13
|
+
coadded depth.
|
|
14
|
+
"""
|
|
15
|
+
|
|
16
|
+
def __init__(self, m5_col="fiveSigmaDepth", nside=128, metric_name="GalaxyCounts", **kwargs):
|
|
17
|
+
self.m5_col = m5_col
|
|
18
|
+
super(GalaxyCountsMetric, self).__init__(col=self.m5_col, metric_name=metric_name, **kwargs)
|
|
19
|
+
# Use the extinction corrected coadded depth metric to calculate
|
|
20
|
+
# the depth at each point.
|
|
21
|
+
self.coaddmetric = ExgalM5(m5_col=self.m5_col)
|
|
22
|
+
# Total of 41253.0 galaxies across the sky (at what magnitude?).
|
|
23
|
+
# This didn't seem to work quite right for me..
|
|
24
|
+
self.scale = 41253.0 / hp.nside2npix(nside) / 5000.0
|
|
25
|
+
# Reset units (otherwise uses magnitudes).
|
|
26
|
+
self.units = "Galaxy Counts"
|
|
27
|
+
|
|
28
|
+
def _gal_count(self, apparent_mag, coaddm5):
|
|
29
|
+
# Order for galCount must be apparent mag, then coaddm5,
|
|
30
|
+
# for scipy.integrate method.
|
|
31
|
+
dn_gal = np.power(10.0, -3.52) * np.power(10.0, 0.34 * apparent_mag)
|
|
32
|
+
completeness = 0.5 * scipy.special.erfc(apparent_mag - coaddm5)
|
|
33
|
+
return dn_gal * completeness
|
|
34
|
+
|
|
35
|
+
def run(self, data_slice, slice_point=None):
|
|
36
|
+
# Calculate the coadded depth.
|
|
37
|
+
coaddm5 = self.coaddmetric.run(data_slice)
|
|
38
|
+
# Calculate the number of galaxies.
|
|
39
|
+
# From Carroll et al, 2014 SPIE (http://arxiv.org/abs/1501.04733)
|
|
40
|
+
# I'm not entirely certain this gives a properly calibrated number
|
|
41
|
+
# of galaxy counts, however it is proportional to the expected number
|
|
42
|
+
# at least (and should be within an order of magnitude)
|
|
43
|
+
num_gal, int_err = scipy.integrate.quad(self._gal_count, -np.inf, 32, args=coaddm5)
|
|
44
|
+
num_gal *= self.scale
|
|
45
|
+
return num_gal
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
# Various things declared here to be imported when running
|
|
2
|
+
# artificialStructureCalculation.
|
|
3
|
+
# Makes the updates easier, since the constants/objects defined here
|
|
4
|
+
# are used by different
|
|
5
|
+
# functions, e.g. power law constants are called by
|
|
6
|
+
# GalaxyCountsMetric_extended as well as
|
|
7
|
+
# GalaxyCounts_withPixelCalibration.
|
|
8
|
+
#
|
|
9
|
+
# Included here:
|
|
10
|
+
# * power law constants from the i-band mock catalog; based on mocks
|
|
11
|
+
# from Padilla et al.
|
|
12
|
+
# * normalization constant for galaxy counts from the mock catalogs.
|
|
13
|
+
#
|
|
14
|
+
# Humna Awan
|
|
15
|
+
# humna.awan@rutgers.edu
|
|
16
|
+
|
|
17
|
+
# Power law constants for each z-bin based on N. D. Padilla et al.'s
|
|
18
|
+
# mock catalogs
|
|
19
|
+
# General power law form: 10**(a*m+b)
|
|
20
|
+
# Declare the dictionary for the power law constants
|
|
21
|
+
from collections import OrderedDict
|
|
22
|
+
|
|
23
|
+
power_law_const_a = OrderedDict()
|
|
24
|
+
power_law_const_b = OrderedDict()
|
|
25
|
+
# 0.<z<0.15
|
|
26
|
+
power_law_const_a["0.<z<0.15"] = 0.166 # July 18 Catalog
|
|
27
|
+
power_law_const_b["0.<z<0.15"] = -0.989 # July 18 Catalog
|
|
28
|
+
|
|
29
|
+
# 0.15<z<0.37
|
|
30
|
+
power_law_const_a["0.15<z<0.37"] = 0.212 # July 18 Catalog
|
|
31
|
+
power_law_const_b["0.15<z<0.37"] = -1.540 # July 18 Catalog
|
|
32
|
+
|
|
33
|
+
# 0.37<z<0.66
|
|
34
|
+
power_law_const_a[" 0.37<z<0.66"] = 0.250 # July 18 Catalog
|
|
35
|
+
power_law_const_b[" 0.37<z<0.66"] = -2.242 # July 18 Catalog
|
|
36
|
+
|
|
37
|
+
# 0.66<z<1.0
|
|
38
|
+
power_law_const_a["0.66<z<1.0"] = 0.265 # July 18 Catalog
|
|
39
|
+
power_law_const_b["0.66<z<1.0"] = -2.660 # July 18 Catalog
|
|
40
|
+
|
|
41
|
+
# 1.0<z<1.5
|
|
42
|
+
power_law_const_a["1.0<z<1.5"] = 0.283 # July 18 Catalog
|
|
43
|
+
power_law_const_b["1.0<z<1.5"] = -3.242 # July 18 Catalog
|
|
44
|
+
|
|
45
|
+
# 1.5<z<2.0
|
|
46
|
+
power_law_const_a["1.5<z<2.0"] = 0.308 # July 18 Catalog
|
|
47
|
+
power_law_const_b["1.5<z<2.0"] = -4.169 # July 18 Catalog
|
|
48
|
+
|
|
49
|
+
# 2.0<z<2.5
|
|
50
|
+
power_law_const_a["2.0<z<2.5"] = 0.364 # July 18 Catalog
|
|
51
|
+
power_law_const_b["2.0<z<2.5"] = -6.261 # July 18 Catalog
|
|
52
|
+
|
|
53
|
+
# 2.5<z<3.0
|
|
54
|
+
power_law_const_a["2.5<z<3.0"] = 0.346 # July 18 Catalog
|
|
55
|
+
power_law_const_b["2.5<z<3.0"] = -5.661 # July 18 Catalog
|
|
56
|
+
|
|
57
|
+
# 3.0<z<3.5
|
|
58
|
+
power_law_const_a["3.0<z<3.5"] = 0.381 # July 18 Catalog
|
|
59
|
+
power_law_const_b["3.0<z<3.5"] = -6.810 # July 18 Catalog
|
|
60
|
+
|
|
61
|
+
# 3.5<z<4.0
|
|
62
|
+
power_law_const_a["3.5<z<4.0"] = 0.424 # July 18 Catalog
|
|
63
|
+
power_law_const_b["3.5<z<4.0"] = -8.362 # July 18 Catalog
|
|
64
|
+
|
|
65
|
+
# 4.0<z<15.0
|
|
66
|
+
power_law_const_a["4.0<z<15.0"] = 0.462 # July 18 Catalog
|
|
67
|
+
power_law_const_b["4.0<z<15.0"] = -9.474 # July 18 Catalog
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
# Normalization to match the total galaxies from mock catalogs to match
|
|
71
|
+
# up to CFHTLS counts for
|
|
72
|
+
# i<25.5 galaxy catalog. Using July 18-19 i-band mock catalogs.
|
|
73
|
+
normalization_constant = 3.70330701802
|