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,162 @@
|
|
|
1
|
+
__all__ = ("BDParallaxMetric", "VolumeSumMetric")
|
|
2
|
+
|
|
3
|
+
import healpy as hp
|
|
4
|
+
import numpy as np
|
|
5
|
+
from scipy import interpolate
|
|
6
|
+
|
|
7
|
+
import rubin_sim.maf.utils as mafUtils
|
|
8
|
+
|
|
9
|
+
from .base_metric import BaseMetric
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
def bd_colors(spec_type):
|
|
13
|
+
"""Returns dictionary of potential Brown Dwarf colors
|
|
14
|
+
|
|
15
|
+
Parameters
|
|
16
|
+
----------
|
|
17
|
+
spec_type : `str`
|
|
18
|
+
The desired spetral type of the Brown Dwarf.
|
|
19
|
+
|
|
20
|
+
"""
|
|
21
|
+
result = {}
|
|
22
|
+
result["L0"] = {"i": 16.00, "z": 14.52, "y": 13.58}
|
|
23
|
+
result["L1"] = {"i": 16.41, "z": 14.93, "y": 13.97}
|
|
24
|
+
result["L2"] = {"i": 16.73, "z": 15.30, "y": 14.33}
|
|
25
|
+
result["L3"] = ({"i": 17.4, "z": 15.88, "y": 14.89},)
|
|
26
|
+
result["L4"] = {"i": 18.35, "z": 16.68, "y": 15.66}
|
|
27
|
+
result["L5"] = {"i": 18.71, "z": 16.94, "y": 15.87}
|
|
28
|
+
result["L6"] = {"i": 19.27, "z": 17.35, "y": 16.27}
|
|
29
|
+
result["L7"] = {"i": 20.09, "z": 18.18, "y": 17.13}
|
|
30
|
+
result["L8"] = {"i": 20.38, "z": 18.10, "y": 17.04}
|
|
31
|
+
result["L9"] = {"i": 20.09, "z": 17.69, "y": 16.57}
|
|
32
|
+
result["T0"] = {"i": 20.22, "z": 17.98, "y": 16.77}
|
|
33
|
+
result["T1"] = {"i": 21.10, "z": 18.84, "y": 17.45}
|
|
34
|
+
result["T2"] = {"i": 21.97, "z": 18.26, "y": 16.75}
|
|
35
|
+
result["T3"] = {"i": 22.50, "z": 18.08, "y": 16.50}
|
|
36
|
+
result["T4"] = {"i": 22.50, "z": 18.02, "y": 16.32}
|
|
37
|
+
result["T5"] = {"i": 22.69, "z": 19.20, "y": 17.43}
|
|
38
|
+
result["T6"] = {"i": 23.00, "z": 19.82, "y": 18.06}
|
|
39
|
+
result["T7"] = {"z": 21.17, "y": 19.34}
|
|
40
|
+
result["T8"] = {"z": 21.52, "y": 19.75}
|
|
41
|
+
result["T9"] = {"z": 21.82, "y": 20.37}
|
|
42
|
+
return result[spec_type]
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
class BDParallaxMetric(BaseMetric):
|
|
46
|
+
"""Calculate the distance to which one could reach a parallax SNR for a
|
|
47
|
+
given object
|
|
48
|
+
|
|
49
|
+
Modification of ParallaxMetric, illustrated in
|
|
50
|
+
https://github.com/jgizis/
|
|
51
|
+
LSST-BD-Cadence/blob/main/bd_allLT_baseline_17.ipynb
|
|
52
|
+
|
|
53
|
+
Uses columns ra_pi_amp and dec_pi_amp,
|
|
54
|
+
calculated by the ParallaxFactorStacker.
|
|
55
|
+
|
|
56
|
+
Parameters
|
|
57
|
+
----------
|
|
58
|
+
metricName : `str`, opt
|
|
59
|
+
Default 'parallax'.
|
|
60
|
+
m5_col : `str`, opt
|
|
61
|
+
The default column name for m5 information in the input data.
|
|
62
|
+
Default fiveSigmaDepth.
|
|
63
|
+
filter_col : `str`, opt
|
|
64
|
+
The column name for the filter information. Default filter.
|
|
65
|
+
seeing_col : `str`, opt
|
|
66
|
+
The column name for the seeing information.
|
|
67
|
+
Since the astrometry errors are based on the physical
|
|
68
|
+
size of the PSF, this should be the FWHM of the physical psf.
|
|
69
|
+
Default seeingFwhmGeom.
|
|
70
|
+
mags : `dict` or None
|
|
71
|
+
The absolute magnitude of the object in question.
|
|
72
|
+
Keys of filter name, values in mags.
|
|
73
|
+
Defaults to an L7 spectral type if None.
|
|
74
|
+
distances : `np.array`, (N,)
|
|
75
|
+
Distances to try putting the object at (pc).
|
|
76
|
+
atm_err : `float`, opt
|
|
77
|
+
The expected centroiding error due to the atmosphere, in arcseconds.
|
|
78
|
+
Default 0.01.
|
|
79
|
+
badval : `float`, opt
|
|
80
|
+
The value to return when the metric value cannot be calculated.
|
|
81
|
+
Default 0.
|
|
82
|
+
"""
|
|
83
|
+
|
|
84
|
+
def __init__(
|
|
85
|
+
self,
|
|
86
|
+
metric_name="bdParallax",
|
|
87
|
+
m5_col="fiveSigmaDepth",
|
|
88
|
+
filter_col="band",
|
|
89
|
+
seeing_col="seeingFwhmGeom",
|
|
90
|
+
badval=0,
|
|
91
|
+
mags=None,
|
|
92
|
+
parallax_snr=10.0,
|
|
93
|
+
distances=np.arange(10, 200, 10),
|
|
94
|
+
atm_err=0.01,
|
|
95
|
+
normalize=False,
|
|
96
|
+
**kwargs,
|
|
97
|
+
):
|
|
98
|
+
cols = [m5_col, filter_col, seeing_col, "ra_pi_amp", "dec_pi_amp"]
|
|
99
|
+
|
|
100
|
+
units = "pc"
|
|
101
|
+
super().__init__(cols, metric_name=metric_name, units=units, badval=badval, **kwargs)
|
|
102
|
+
# set return types
|
|
103
|
+
self.m5_col = m5_col
|
|
104
|
+
self.seeing_col = seeing_col
|
|
105
|
+
self.filter_col = filter_col
|
|
106
|
+
self.distances = distances
|
|
107
|
+
self.mags = {}
|
|
108
|
+
distance_mod = 5.0 * np.log10(distances) - 5.0
|
|
109
|
+
if mags is None:
|
|
110
|
+
mags = bd_colors("L7")
|
|
111
|
+
for key in mags:
|
|
112
|
+
self.mags[key] = mags[key] + distance_mod
|
|
113
|
+
self.parallax_snr_goal = parallax_snr
|
|
114
|
+
self.atm_err = atm_err
|
|
115
|
+
self.filters = list(self.mags.keys())
|
|
116
|
+
self.parallaxes = 1000.0 / distances # mas
|
|
117
|
+
|
|
118
|
+
def _final_sigma(self, position_errors, ra_pi_amp, dec_pi_amp):
|
|
119
|
+
"""Assume parallax in RA and DEC are fit independently, then combined.
|
|
120
|
+
All inputs assumed to be arcsec.
|
|
121
|
+
"""
|
|
122
|
+
sigma_a = position_errors / ra_pi_amp
|
|
123
|
+
sigma_b = position_errors / dec_pi_amp
|
|
124
|
+
sigma_ra = np.sqrt(1.0 / np.sum(1.0 / sigma_a**2, axis=1))
|
|
125
|
+
sigma_dec = np.sqrt(1.0 / np.sum(1.0 / sigma_b**2, axis=1))
|
|
126
|
+
# Combine RA and Dec uncertainties, convert to mas
|
|
127
|
+
sigma = np.sqrt(1.0 / (1.0 / sigma_ra**2 + 1.0 / sigma_dec**2)) * 1e3
|
|
128
|
+
return sigma
|
|
129
|
+
|
|
130
|
+
def run(self, data_slice, slice_point=None):
|
|
131
|
+
snr = np.zeros((np.size(self.mags[self.filters[0]]), len(data_slice)), dtype="float")
|
|
132
|
+
# compute SNR for all observations
|
|
133
|
+
for filt in self.filters:
|
|
134
|
+
good = np.where(data_slice[self.filter_col] == filt)[0]
|
|
135
|
+
if np.size(good) > 0:
|
|
136
|
+
snr[:, good] = mafUtils.m52snr(
|
|
137
|
+
self.mags[str(filt)][:, np.newaxis], data_slice[self.m5_col][good]
|
|
138
|
+
)
|
|
139
|
+
|
|
140
|
+
position_errors = mafUtils.astrom_precision(data_slice[self.seeing_col], snr, self.atm_err)
|
|
141
|
+
# uncertainty in the parallax in mas
|
|
142
|
+
sigma = self._final_sigma(position_errors, data_slice["ra_pi_amp"], data_slice["dec_pi_amp"])
|
|
143
|
+
fitted_parallax_snr = self.parallaxes / sigma
|
|
144
|
+
result = self.badval
|
|
145
|
+
# Let's interpolate to the distance where we would get our target SNR
|
|
146
|
+
if np.max(fitted_parallax_snr) >= self.parallax_snr_goal:
|
|
147
|
+
f = interpolate.interp1d(fitted_parallax_snr, self.distances, fill_value="extrapolate")
|
|
148
|
+
result = f(self.parallax_snr_goal)
|
|
149
|
+
return result
|
|
150
|
+
|
|
151
|
+
|
|
152
|
+
class VolumeSumMetric(BaseMetric):
|
|
153
|
+
"""Compute the total volume assuming a metric has values of distance."""
|
|
154
|
+
|
|
155
|
+
def __init__(self, col=None, metric_name="VolumeSum", nside=None, **kwargs):
|
|
156
|
+
super(VolumeSumMetric, self).__init__(col=col, metric_name=metric_name, **kwargs)
|
|
157
|
+
self.pix_area = hp.nside2pixarea(nside)
|
|
158
|
+
|
|
159
|
+
def run(self, data_slice, slice_point=None):
|
|
160
|
+
# volume of sphere, times ratio of pixel area divided by area of sphere
|
|
161
|
+
vols = 1.0 / 3.0 * data_slice[self.colname] ** 3 * self.pix_area
|
|
162
|
+
return np.sum(vols)
|
|
@@ -0,0 +1,400 @@
|
|
|
1
|
+
__all__ = (
|
|
2
|
+
"TemplateExistsMetric",
|
|
3
|
+
"UniformityMetric",
|
|
4
|
+
"GeneralUniformityMetric",
|
|
5
|
+
"RapidRevisitUniformityMetric",
|
|
6
|
+
"RapidRevisitMetric",
|
|
7
|
+
"NRevisitsMetric",
|
|
8
|
+
"IntraNightGapsMetric",
|
|
9
|
+
"InterNightGapsMetric",
|
|
10
|
+
"VisitGapMetric",
|
|
11
|
+
)
|
|
12
|
+
|
|
13
|
+
import numpy as np
|
|
14
|
+
|
|
15
|
+
from .base_metric import BaseMetric
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
class FSMetric(BaseMetric):
|
|
19
|
+
"""Calculate the fS value (Nvisit-weighted delta(M5-M5srd))."""
|
|
20
|
+
|
|
21
|
+
def __init__(self, filter_col="band", metric_name="fS", **kwargs):
|
|
22
|
+
self.filter_col = filter_col
|
|
23
|
+
cols = [self.filter_col]
|
|
24
|
+
super().__init__(cols=cols, metric_name=metric_name, units="fS", **kwargs)
|
|
25
|
+
|
|
26
|
+
def run(self, data_slice, slice_point=None):
|
|
27
|
+
# We could import this from the m5_flat_sed values,
|
|
28
|
+
# but it makes sense to calculate the m5
|
|
29
|
+
# directly from the throughputs. This is easy enough to do and
|
|
30
|
+
# will allow variation of
|
|
31
|
+
# the throughput curves and readnoise and visit length, etc.
|
|
32
|
+
pass
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
class TemplateExistsMetric(BaseMetric):
|
|
36
|
+
"""Calculate the fraction of images with a previous template
|
|
37
|
+
image of desired quality."""
|
|
38
|
+
|
|
39
|
+
def __init__(
|
|
40
|
+
self,
|
|
41
|
+
seeing_col="seeingFwhmGeom",
|
|
42
|
+
observation_start_mjd_col="observationStartMJD",
|
|
43
|
+
metric_name="TemplateExistsMetric",
|
|
44
|
+
**kwargs,
|
|
45
|
+
):
|
|
46
|
+
cols = [seeing_col, observation_start_mjd_col]
|
|
47
|
+
super(TemplateExistsMetric, self).__init__(
|
|
48
|
+
col=cols, metric_name=metric_name, units="fraction", **kwargs
|
|
49
|
+
)
|
|
50
|
+
self.seeing_col = seeing_col
|
|
51
|
+
self.observation_start_mjd_col = observation_start_mjd_col
|
|
52
|
+
|
|
53
|
+
def run(self, data_slice, slice_point=None):
|
|
54
|
+
# Check that data is sorted in observationStartMJD order
|
|
55
|
+
data_slice.sort(order=self.observation_start_mjd_col)
|
|
56
|
+
# Find the minimum seeing up to a given time
|
|
57
|
+
seeing_mins = np.minimum.accumulate(data_slice[self.seeing_col])
|
|
58
|
+
# Find the difference between the seeing and the minimum seeing
|
|
59
|
+
# at the previous visit
|
|
60
|
+
seeing_diff = data_slice[self.seeing_col] - np.roll(seeing_mins, 1)
|
|
61
|
+
# First image never has a template; check how many others do
|
|
62
|
+
good = np.where(seeing_diff[1:] >= 0.0)[0]
|
|
63
|
+
frac = (good.size) / float(data_slice[self.seeing_col].size)
|
|
64
|
+
return frac
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
class UniformityMetric(BaseMetric):
|
|
68
|
+
"""Calculate how uniformly the observations are spaced in time.
|
|
69
|
+
|
|
70
|
+
This is based on how a KS-test works:
|
|
71
|
+
look at the cumulative distribution of observation dates,
|
|
72
|
+
and compare to a perfectly uniform cumulative distribution.
|
|
73
|
+
Perfectly uniform observations = 0, perfectly non-uniform = 1.
|
|
74
|
+
|
|
75
|
+
Parameters
|
|
76
|
+
----------
|
|
77
|
+
mjd_col : `str`, optional
|
|
78
|
+
The column containing time for each observation.
|
|
79
|
+
Default "observationStartMJD".
|
|
80
|
+
survey_length : `float`, optional
|
|
81
|
+
The overall duration of the survey. Default 10.
|
|
82
|
+
"""
|
|
83
|
+
|
|
84
|
+
def __init__(self, mjd_col="observationStartMJD", units="", survey_length=10.0, **kwargs):
|
|
85
|
+
"""survey_length = time span of survey (years)"""
|
|
86
|
+
self.mjd_col = mjd_col
|
|
87
|
+
super(UniformityMetric, self).__init__(col=self.mjd_col, units=units, **kwargs)
|
|
88
|
+
self.survey_length = survey_length
|
|
89
|
+
|
|
90
|
+
def run(self, data_slice, slice_point=None):
|
|
91
|
+
# If only one observation, there is no uniformity
|
|
92
|
+
if data_slice[self.mjd_col].size == 1:
|
|
93
|
+
return 1
|
|
94
|
+
# Scale dates to lie between 0 and 1,
|
|
95
|
+
# where 0 is the first observation date and 1 is surveyLength
|
|
96
|
+
dates = (data_slice[self.mjd_col] - data_slice[self.mjd_col].min()) / (self.survey_length * 365.25)
|
|
97
|
+
dates.sort() # Just to be sure
|
|
98
|
+
n_cum = np.arange(1, dates.size + 1) / float(dates.size)
|
|
99
|
+
d_max = np.max(np.abs(n_cum - dates - dates[1]))
|
|
100
|
+
return d_max
|
|
101
|
+
|
|
102
|
+
|
|
103
|
+
class GeneralUniformityMetric(BaseMetric):
|
|
104
|
+
"""Calculate how uniformly any values are distributed.
|
|
105
|
+
|
|
106
|
+
This is based on how a KS-test works:
|
|
107
|
+
look at the cumulative distribution of data,
|
|
108
|
+
and compare to a perfectly uniform cumulative distribution.
|
|
109
|
+
Perfectly uniform observations = 0, perfectly non-uniform = 1.
|
|
110
|
+
To be "perfectly uniform" here, the endpoints need to be included.
|
|
111
|
+
|
|
112
|
+
Parameters
|
|
113
|
+
----------
|
|
114
|
+
col : `str`, optional
|
|
115
|
+
The column of data to use for the metric.
|
|
116
|
+
The default is "observationStartMJD" as this is most
|
|
117
|
+
typically used with time.
|
|
118
|
+
min_value : `float`, optional
|
|
119
|
+
The minimum value expected for the data.
|
|
120
|
+
Default None will calculate use the minimum value in this dataslice
|
|
121
|
+
(which may not cover the full range).
|
|
122
|
+
max_value : `float`, optional
|
|
123
|
+
The maximum value expected for the data.
|
|
124
|
+
Default None will calculate use the maximum value in this dataslice
|
|
125
|
+
(which may not cover the full range).
|
|
126
|
+
"""
|
|
127
|
+
|
|
128
|
+
def __init__(self, col="observationStartMJD", units="", min_value=None, max_value=None, **kwargs):
|
|
129
|
+
self.col = col
|
|
130
|
+
super().__init__(col=self.col, units=units, **kwargs)
|
|
131
|
+
self.min_value = min_value
|
|
132
|
+
self.max_value = max_value
|
|
133
|
+
|
|
134
|
+
def run(self, data_slice, slice_point=None):
|
|
135
|
+
# If only one observation, there is no uniformity
|
|
136
|
+
if data_slice[self.col].size == 1:
|
|
137
|
+
return 1
|
|
138
|
+
# Scale values to lie between 0 and 1,
|
|
139
|
+
# where 0 is the min_value and 1 is max_value
|
|
140
|
+
if self.min_value is None:
|
|
141
|
+
min_value = data_slice[self.col].min()
|
|
142
|
+
else:
|
|
143
|
+
min_value = self.min_value
|
|
144
|
+
if self.max_value is None:
|
|
145
|
+
max_value = data_slice[self.col].max()
|
|
146
|
+
else:
|
|
147
|
+
max_value = self.max_value
|
|
148
|
+
scaled_values = (data_slice[self.col] - min_value) / max_value
|
|
149
|
+
scaled_values.sort() # Just to be sure
|
|
150
|
+
n_cum = np.arange(0, scaled_values.size) / float(scaled_values.size - 1)
|
|
151
|
+
d_max = np.max(np.abs(n_cum - scaled_values))
|
|
152
|
+
return d_max
|
|
153
|
+
|
|
154
|
+
|
|
155
|
+
class RapidRevisitUniformityMetric(BaseMetric):
|
|
156
|
+
"""Calculate uniformity of time between consecutive visits on
|
|
157
|
+
short timescales (for RAV1).
|
|
158
|
+
|
|
159
|
+
Uses the same 'uniformity' calculation as the UniformityMetric,
|
|
160
|
+
based on the KS-test.
|
|
161
|
+
A value of 0 is perfectly uniform; a value of 1 is purely non-uniform.
|
|
162
|
+
|
|
163
|
+
Parameters
|
|
164
|
+
----------
|
|
165
|
+
mjd_col : `str`, optional
|
|
166
|
+
The column containing the 'time' value. Default observationStartMJD.
|
|
167
|
+
min_nvisits : `int`, optional
|
|
168
|
+
The minimum number of visits required within the
|
|
169
|
+
time interval (d_tmin to d_tmax).
|
|
170
|
+
Default 100.
|
|
171
|
+
d_tmin : `float`, optional
|
|
172
|
+
The minimum dTime to consider (in days). Default 40 seconds.
|
|
173
|
+
d_tmax : `float`, optional
|
|
174
|
+
The maximum dTime to consider (in days). Default 30 minutes.
|
|
175
|
+
"""
|
|
176
|
+
|
|
177
|
+
def __init__(
|
|
178
|
+
self,
|
|
179
|
+
mjd_col="observationStartMJD",
|
|
180
|
+
min_nvisits=100,
|
|
181
|
+
d_tmin=40.0 / 60.0 / 60.0 / 24.0,
|
|
182
|
+
d_tmax=30.0 / 60.0 / 24.0,
|
|
183
|
+
metric_name="RapidRevisitUniformity",
|
|
184
|
+
**kwargs,
|
|
185
|
+
):
|
|
186
|
+
self.mjd_col = mjd_col
|
|
187
|
+
self.min_nvisits = min_nvisits
|
|
188
|
+
self.d_tmin = d_tmin
|
|
189
|
+
self.d_tmax = d_tmax
|
|
190
|
+
super().__init__(col=self.mjd_col, metric_name=metric_name, **kwargs)
|
|
191
|
+
# Update min_nvisits, as 0 visits will crash algorithm
|
|
192
|
+
# and 1 is nonuniform by definition.
|
|
193
|
+
if self.min_nvisits <= 1:
|
|
194
|
+
self.min_nvisits = 2
|
|
195
|
+
|
|
196
|
+
def run(self, data_slice, slice_point=None):
|
|
197
|
+
# Calculate consecutive visit time intervals
|
|
198
|
+
dtimes = np.diff(np.sort(data_slice[self.mjd_col]))
|
|
199
|
+
# Identify dtimes within interval from dTmin/dTmax.
|
|
200
|
+
good = np.where((dtimes >= self.d_tmin) & (dtimes <= self.d_tmax))[0]
|
|
201
|
+
# If there are not enough visits in this time range, return bad value.
|
|
202
|
+
if good.size < self.min_nvisits:
|
|
203
|
+
return self.badval
|
|
204
|
+
# Throw out dtimes outside desired range, and sort, then scale to 0-1.
|
|
205
|
+
dtimes = np.sort(dtimes[good])
|
|
206
|
+
dtimes = (dtimes - dtimes.min()) / float(self.d_tmax - self.d_tmin)
|
|
207
|
+
# Set up a uniform distribution between 0-1 (to match dtimes).
|
|
208
|
+
uniform_dtimes = np.arange(1, dtimes.size + 1, 1) / float(dtimes.size)
|
|
209
|
+
# Look at the differences between our times and the uniform times.
|
|
210
|
+
dmax = np.max(np.abs(uniform_dtimes - dtimes - dtimes[1]))
|
|
211
|
+
return dmax
|
|
212
|
+
|
|
213
|
+
|
|
214
|
+
class RapidRevisitMetric(BaseMetric):
|
|
215
|
+
def __init__(
|
|
216
|
+
self,
|
|
217
|
+
mjd_col="observationStartMJD",
|
|
218
|
+
metric_name="RapidRevisit",
|
|
219
|
+
d_tmin=40.0 / 60.0 / 60.0 / 24.0,
|
|
220
|
+
d_tpairs=20.0 / 60.0 / 24.0,
|
|
221
|
+
d_tmax=30.0 / 60.0 / 24.0,
|
|
222
|
+
min_n1=28,
|
|
223
|
+
min_n2=82,
|
|
224
|
+
**kwargs,
|
|
225
|
+
):
|
|
226
|
+
self.mjd_col = mjd_col
|
|
227
|
+
self.d_tmin = d_tmin
|
|
228
|
+
self.d_tpairs = d_tpairs
|
|
229
|
+
self.d_tmax = d_tmax
|
|
230
|
+
self.min_n1 = min_n1
|
|
231
|
+
self.min_n2 = min_n2
|
|
232
|
+
super().__init__(col=self.mjd_col, metric_name=metric_name, **kwargs)
|
|
233
|
+
|
|
234
|
+
def run(self, data_slice, slice_point=None):
|
|
235
|
+
dtimes = np.diff(np.sort(data_slice[self.mjd_col]))
|
|
236
|
+
n1 = len(np.where((dtimes >= self.d_tmin) & (dtimes <= self.d_tpairs))[0])
|
|
237
|
+
n2 = len(np.where((dtimes >= self.d_tmin) & (dtimes <= self.d_tmax))[0])
|
|
238
|
+
if (n1 >= self.min_n1) and (n2 >= self.min_n2):
|
|
239
|
+
val = 1
|
|
240
|
+
else:
|
|
241
|
+
val = 0
|
|
242
|
+
return val
|
|
243
|
+
|
|
244
|
+
|
|
245
|
+
class NRevisitsMetric(BaseMetric):
|
|
246
|
+
"""Calculate the number of consecutive visits with
|
|
247
|
+
time differences less than d_t.
|
|
248
|
+
|
|
249
|
+
Parameters
|
|
250
|
+
----------
|
|
251
|
+
d_t : `float`, optional
|
|
252
|
+
The time interval to consider (in minutes). Default 30.
|
|
253
|
+
normed : `bool`, optional
|
|
254
|
+
Flag to indicate whether to return the total number of
|
|
255
|
+
consecutive visits with time differences less than d_t (False),
|
|
256
|
+
or the fraction of overall visits (True).
|
|
257
|
+
Note that we would expect (if all visits occur in pairs within d_t)
|
|
258
|
+
this fraction would be 0.5!
|
|
259
|
+
"""
|
|
260
|
+
|
|
261
|
+
def __init__(self, mjd_col="observationStartMJD", d_t=30.0, normed=False, metric_name=None, **kwargs):
|
|
262
|
+
units = ""
|
|
263
|
+
if metric_name is None:
|
|
264
|
+
if normed:
|
|
265
|
+
metric_name = "Fraction of revisits faster than %.1f minutes" % (d_t)
|
|
266
|
+
else:
|
|
267
|
+
metric_name = "Number of revisits faster than %.1f minutes" % (d_t)
|
|
268
|
+
units = "#"
|
|
269
|
+
self.mjd_col = mjd_col
|
|
270
|
+
self.d_t = d_t / 60.0 / 24.0 # convert to days
|
|
271
|
+
self.normed = normed
|
|
272
|
+
super(NRevisitsMetric, self).__init__(
|
|
273
|
+
col=self.mjd_col, units=units, metric_name=metric_name, **kwargs
|
|
274
|
+
)
|
|
275
|
+
|
|
276
|
+
def run(self, data_slice, slice_point=None):
|
|
277
|
+
dtimes = np.diff(np.sort(data_slice[self.mjd_col]))
|
|
278
|
+
n_fast_revisits = np.size(np.where(dtimes <= self.d_t)[0])
|
|
279
|
+
if self.normed:
|
|
280
|
+
n_fast_revisits = n_fast_revisits / float(np.size(data_slice[self.mjd_col]))
|
|
281
|
+
return n_fast_revisits
|
|
282
|
+
|
|
283
|
+
|
|
284
|
+
class IntraNightGapsMetric(BaseMetric):
|
|
285
|
+
"""
|
|
286
|
+
Calculate the (reduce_func) of the gap between consecutive
|
|
287
|
+
observations within a night, in hours.
|
|
288
|
+
|
|
289
|
+
Parameters
|
|
290
|
+
----------
|
|
291
|
+
reduce_func : function, optional
|
|
292
|
+
Function that can operate on array-like structures.
|
|
293
|
+
Typically numpy function.
|
|
294
|
+
Default np.median.
|
|
295
|
+
"""
|
|
296
|
+
|
|
297
|
+
def __init__(
|
|
298
|
+
self,
|
|
299
|
+
mjd_col="observationStartMJD",
|
|
300
|
+
night_col="night",
|
|
301
|
+
reduce_func=np.median,
|
|
302
|
+
metric_name="Median Intra-Night Gap",
|
|
303
|
+
**kwargs,
|
|
304
|
+
):
|
|
305
|
+
units = "hours"
|
|
306
|
+
self.mjd_col = mjd_col
|
|
307
|
+
self.night_col = night_col
|
|
308
|
+
self.reduce_func = reduce_func
|
|
309
|
+
super(IntraNightGapsMetric, self).__init__(
|
|
310
|
+
col=[self.mjd_col, self.night_col], units=units, metric_name=metric_name, **kwargs
|
|
311
|
+
)
|
|
312
|
+
|
|
313
|
+
def run(self, data_slice, slice_point=None):
|
|
314
|
+
data_slice.sort(order=self.mjd_col)
|
|
315
|
+
dt = np.diff(data_slice[self.mjd_col])
|
|
316
|
+
dn = np.diff(data_slice[self.night_col])
|
|
317
|
+
|
|
318
|
+
good = np.where(dn == 0)
|
|
319
|
+
if np.size(good[0]) == 0:
|
|
320
|
+
result = self.badval
|
|
321
|
+
else:
|
|
322
|
+
result = self.reduce_func(dt[good]) * 24
|
|
323
|
+
return result
|
|
324
|
+
|
|
325
|
+
|
|
326
|
+
class InterNightGapsMetric(BaseMetric):
|
|
327
|
+
"""Calculate the (reduce_func) of the gap between consecutive
|
|
328
|
+
observations in different nights, in days.
|
|
329
|
+
|
|
330
|
+
Parameters
|
|
331
|
+
----------
|
|
332
|
+
reduce_func : function, optional
|
|
333
|
+
Function that can operate on array-like structures.
|
|
334
|
+
Typically numpy function.
|
|
335
|
+
Default np.median.
|
|
336
|
+
"""
|
|
337
|
+
|
|
338
|
+
def __init__(
|
|
339
|
+
self,
|
|
340
|
+
mjd_col="observationStartMJD",
|
|
341
|
+
night_col="night",
|
|
342
|
+
reduce_func=np.median,
|
|
343
|
+
metric_name="Median Inter-Night Gap",
|
|
344
|
+
**kwargs,
|
|
345
|
+
):
|
|
346
|
+
units = "days"
|
|
347
|
+
self.mjd_col = mjd_col
|
|
348
|
+
self.night_col = night_col
|
|
349
|
+
self.reduce_func = reduce_func
|
|
350
|
+
super().__init__(col=[self.mjd_col, self.night_col], units=units, metric_name=metric_name, **kwargs)
|
|
351
|
+
|
|
352
|
+
def run(self, data_slice, slice_point=None):
|
|
353
|
+
data_slice.sort(order=self.mjd_col)
|
|
354
|
+
unights = np.unique(data_slice[self.night_col])
|
|
355
|
+
if np.size(unights) < 2:
|
|
356
|
+
result = self.badval
|
|
357
|
+
else:
|
|
358
|
+
# Find the first and last observation of each night
|
|
359
|
+
first_of_night = np.searchsorted(data_slice[self.night_col], unights)
|
|
360
|
+
last_of_night = np.searchsorted(data_slice[self.night_col], unights, side="right") - 1
|
|
361
|
+
diff = data_slice[self.mjd_col][first_of_night[1:]] - data_slice[self.mjd_col][last_of_night[:-1]]
|
|
362
|
+
result = self.reduce_func(diff)
|
|
363
|
+
return result
|
|
364
|
+
|
|
365
|
+
|
|
366
|
+
class VisitGapMetric(BaseMetric):
|
|
367
|
+
"""Calculate the (reduce_func) of the gap between any
|
|
368
|
+
consecutive observations, in hours, regardless of night boundaries.
|
|
369
|
+
|
|
370
|
+
Different from inter-night and intra-night gaps,
|
|
371
|
+
because this is really just counting all of the times between consecutive
|
|
372
|
+
observations (not time between nights or time within a night).
|
|
373
|
+
|
|
374
|
+
Parameters
|
|
375
|
+
----------
|
|
376
|
+
reduce_func : function, optional
|
|
377
|
+
Function that can operate on array-like structures.
|
|
378
|
+
Typically numpy function.
|
|
379
|
+
Default np.median.
|
|
380
|
+
"""
|
|
381
|
+
|
|
382
|
+
def __init__(
|
|
383
|
+
self,
|
|
384
|
+
mjd_col="observationStartMJD",
|
|
385
|
+
night_col="night",
|
|
386
|
+
reduce_func=np.median,
|
|
387
|
+
metric_name="VisitGap",
|
|
388
|
+
**kwargs,
|
|
389
|
+
):
|
|
390
|
+
units = "hours"
|
|
391
|
+
self.mjd_col = mjd_col
|
|
392
|
+
self.night_col = night_col
|
|
393
|
+
self.reduce_func = reduce_func
|
|
394
|
+
super().__init__(col=[self.mjd_col, self.night_col], units=units, metric_name=metric_name, **kwargs)
|
|
395
|
+
|
|
396
|
+
def run(self, data_slice, slice_point=None):
|
|
397
|
+
data_slice.sort(order=self.mjd_col)
|
|
398
|
+
diff = np.diff(data_slice[self.mjd_col])
|
|
399
|
+
result = self.reduce_func(diff) * 24.0
|
|
400
|
+
return result
|