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,645 @@
|
|
|
1
|
+
__all__ = ("MafRunResults",)
|
|
2
|
+
|
|
3
|
+
import os
|
|
4
|
+
import re
|
|
5
|
+
from collections import OrderedDict
|
|
6
|
+
|
|
7
|
+
import numpy as np
|
|
8
|
+
|
|
9
|
+
import rubin_sim.maf.db as db
|
|
10
|
+
import rubin_sim.maf.metric_bundles as metricBundles
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class MafRunResults:
|
|
14
|
+
"""Read and serve the MAF resultsDb_sqlite.db database for the
|
|
15
|
+
show_maf jinja2 templates.
|
|
16
|
+
|
|
17
|
+
Deals with a single MAF run (one output directory, one results_db) only.
|
|
18
|
+
|
|
19
|
+
Parameters
|
|
20
|
+
----------
|
|
21
|
+
out_dir : `str`
|
|
22
|
+
The location of the results database for this run.
|
|
23
|
+
run_name : `str`, optional
|
|
24
|
+
The name of the opsim run.
|
|
25
|
+
If None, simply stays blank on show_maf display pages.
|
|
26
|
+
results_db : `str`, optional
|
|
27
|
+
The path to the sqlite database in `out_dir`.
|
|
28
|
+
If None, uses the default of `resultsDb_sqlite.db`.
|
|
29
|
+
"""
|
|
30
|
+
|
|
31
|
+
def __init__(self, out_dir, run_name=None, results_db=None):
|
|
32
|
+
self.out_dir = os.path.relpath(out_dir, ".")
|
|
33
|
+
self.run_name = run_name
|
|
34
|
+
|
|
35
|
+
# Read in the results database.
|
|
36
|
+
if results_db is None:
|
|
37
|
+
results_db = os.path.join(self.out_dir, "resultsDb_sqlite.db")
|
|
38
|
+
database = db.ResultsDb(database=results_db)
|
|
39
|
+
|
|
40
|
+
# Get the metric and display info (1-1 match)
|
|
41
|
+
self.metrics = database.get_metric_display_info()
|
|
42
|
+
self.metrics = self.sort_metrics(self.metrics)
|
|
43
|
+
|
|
44
|
+
# Get the plot and stats info (many-1 metric match)
|
|
45
|
+
skip_stats = ["Completeness@Time", "Completeness H", "FractionPop "]
|
|
46
|
+
self.stats = database.get_summary_stats(summary_name_notlike=skip_stats)
|
|
47
|
+
self.plots = database.get_plot_files()
|
|
48
|
+
|
|
49
|
+
# Pull up the names of the groups and subgroups.
|
|
50
|
+
groups = sorted(np.unique(self.metrics["display_group"]))
|
|
51
|
+
self.groups = OrderedDict()
|
|
52
|
+
for g in groups:
|
|
53
|
+
group_metrics = self.metrics[np.where(self.metrics["display_group"] == g)]
|
|
54
|
+
self.groups[g] = sorted(np.unique(group_metrics["display_subgroup"]))
|
|
55
|
+
|
|
56
|
+
self.summary_stat_order = [
|
|
57
|
+
"Id",
|
|
58
|
+
"Identity",
|
|
59
|
+
"Median",
|
|
60
|
+
"Mean",
|
|
61
|
+
"Rms",
|
|
62
|
+
"RobustRms",
|
|
63
|
+
"N(-3Sigma)",
|
|
64
|
+
"N(+3Sigma)",
|
|
65
|
+
"Count",
|
|
66
|
+
"25th%ile",
|
|
67
|
+
"75th%ile",
|
|
68
|
+
"Min",
|
|
69
|
+
"Max",
|
|
70
|
+
]
|
|
71
|
+
# Add in the table fraction sorting to summary stat ordering.
|
|
72
|
+
table_fractions = [
|
|
73
|
+
x for x in list(np.unique(self.stats["summary_metric"])) if x.startswith("TableFraction")
|
|
74
|
+
]
|
|
75
|
+
if len(table_fractions) > 0:
|
|
76
|
+
for x in (
|
|
77
|
+
"TableFraction 0 == P",
|
|
78
|
+
"TableFraction 1 == P",
|
|
79
|
+
"TableFraction 1 < P",
|
|
80
|
+
):
|
|
81
|
+
if x in table_fractions:
|
|
82
|
+
table_fractions.remove(x)
|
|
83
|
+
table_fractions = sorted(table_fractions)
|
|
84
|
+
self.summary_stat_order.append("TableFraction 0 == P")
|
|
85
|
+
for table_frac in table_fractions:
|
|
86
|
+
self.summary_stat_order.append(table_frac)
|
|
87
|
+
self.summary_stat_order.append("TableFraction 1 == P")
|
|
88
|
+
self.summary_stat_order.append("TableFraction 1 < P")
|
|
89
|
+
|
|
90
|
+
self.plot_order = ["SkyMap", "Histogram", "PowerSpectrum", "Combo"]
|
|
91
|
+
|
|
92
|
+
# Methods to deal with metricIds
|
|
93
|
+
|
|
94
|
+
def convert_select_to_metrics(self, group_list, metric_id_list):
|
|
95
|
+
"""
|
|
96
|
+
Convert the lists of values returned by 'select metrics' template page
|
|
97
|
+
into an appropriate dataframe of metrics (in sorted order).
|
|
98
|
+
|
|
99
|
+
Parameters
|
|
100
|
+
----------
|
|
101
|
+
group_list : `list` [`str`]
|
|
102
|
+
The groups of metrics to show on the show_maf pages.
|
|
103
|
+
metric_id_list : `list` [`int`]
|
|
104
|
+
The integer ids of the metrics in the sqlite results database.
|
|
105
|
+
|
|
106
|
+
Returns
|
|
107
|
+
-------
|
|
108
|
+
metrics : `np.ndarray`, (N,)
|
|
109
|
+
An array of the metric information for the metrics .
|
|
110
|
+
"""
|
|
111
|
+
metric_ids = set()
|
|
112
|
+
for group_subgroup in group_list:
|
|
113
|
+
group = group_subgroup.split("_")[0]
|
|
114
|
+
subgroup = group_subgroup.split("_")[-1].replace("+", " ")
|
|
115
|
+
m_ids = self.metric_ids_in_subgroup(group, subgroup)
|
|
116
|
+
for m_id in m_ids:
|
|
117
|
+
metric_ids.add(m_id)
|
|
118
|
+
for m_id in metric_id_list:
|
|
119
|
+
m_id = int(m_id)
|
|
120
|
+
metric_ids.add(m_id)
|
|
121
|
+
metric_ids = list(metric_ids)
|
|
122
|
+
metrics = self.metric_ids_to_metrics(metric_ids)
|
|
123
|
+
metrics = self.sort_metrics(metrics)
|
|
124
|
+
return metrics
|
|
125
|
+
|
|
126
|
+
def get_json(self, metric):
|
|
127
|
+
"""
|
|
128
|
+
Return the JSON string containing the data for a particular metric.
|
|
129
|
+
"""
|
|
130
|
+
if len(metric) > 1:
|
|
131
|
+
return None
|
|
132
|
+
metric = metric[0]
|
|
133
|
+
filename = metric["metric_datafile"]
|
|
134
|
+
if filename.upper() == "NULL":
|
|
135
|
+
return None
|
|
136
|
+
datafile = os.path.join(self.out_dir, filename)
|
|
137
|
+
# Read data back into a bundle.
|
|
138
|
+
m_b = metricBundles.create_empty_metric_bundle()
|
|
139
|
+
m_b.read(datafile)
|
|
140
|
+
io = m_b.output_json()
|
|
141
|
+
if io is None:
|
|
142
|
+
return None
|
|
143
|
+
return io.get_value()
|
|
144
|
+
|
|
145
|
+
def get_npz(self, metric):
|
|
146
|
+
"""
|
|
147
|
+
Return the npz data.
|
|
148
|
+
"""
|
|
149
|
+
if len(metric) > 1:
|
|
150
|
+
return None
|
|
151
|
+
metric = metric[0]
|
|
152
|
+
filename = metric["metric_datafile"]
|
|
153
|
+
if filename.upper() == "NULL":
|
|
154
|
+
return None
|
|
155
|
+
else:
|
|
156
|
+
datafile = os.path.join(self.out_dir, filename)
|
|
157
|
+
return datafile
|
|
158
|
+
|
|
159
|
+
def get_results_db(self):
|
|
160
|
+
"""
|
|
161
|
+
Return the summary results sqlite filename, as long as the
|
|
162
|
+
results data is named `resultsDb_sqlite.db`.
|
|
163
|
+
"""
|
|
164
|
+
return os.path.join(self.out_dir, "resultsDb_sqlite.db")
|
|
165
|
+
|
|
166
|
+
def metric_ids_in_subgroup(self, group, subgroup):
|
|
167
|
+
"""
|
|
168
|
+
Return the metric_ids within a given group/subgroup.
|
|
169
|
+
"""
|
|
170
|
+
metrics = self.metrics_in_subgroup(group, subgroup)
|
|
171
|
+
metric_ids = list(metrics["metric_id"])
|
|
172
|
+
return metric_ids
|
|
173
|
+
|
|
174
|
+
def metric_ids_to_metrics(self, metric_ids, metrics=None):
|
|
175
|
+
"""
|
|
176
|
+
Return an ordered numpy array of metrics matching metric_ids.
|
|
177
|
+
"""
|
|
178
|
+
if metrics is None:
|
|
179
|
+
metrics = self.metrics
|
|
180
|
+
metrics = metrics[np.isin(metrics["metric_id"], metric_ids)]
|
|
181
|
+
return metrics
|
|
182
|
+
|
|
183
|
+
def metrics_to_metric_ids(self, metrics):
|
|
184
|
+
"""
|
|
185
|
+
Return a list of the metric Ids corresponding to a subset of metrics.
|
|
186
|
+
"""
|
|
187
|
+
return list(metrics["metric_id"])
|
|
188
|
+
|
|
189
|
+
# Methods to deal with metrics in numpy recarray.
|
|
190
|
+
|
|
191
|
+
def sort_metrics(
|
|
192
|
+
self,
|
|
193
|
+
metrics,
|
|
194
|
+
order=(
|
|
195
|
+
"display_group",
|
|
196
|
+
"display_subgroup",
|
|
197
|
+
"base_metric_name",
|
|
198
|
+
"slicer_name",
|
|
199
|
+
"display_order",
|
|
200
|
+
"metric_info_label",
|
|
201
|
+
),
|
|
202
|
+
):
|
|
203
|
+
"""
|
|
204
|
+
Sort the metrics by order specified by 'order'.
|
|
205
|
+
|
|
206
|
+
Default is to sort by group, subgroup, metric name, slicer,
|
|
207
|
+
display order, then info_label.
|
|
208
|
+
Returns sorted numpy array.
|
|
209
|
+
"""
|
|
210
|
+
if len(metrics) > 0:
|
|
211
|
+
metrics = np.sort(metrics, order=order)
|
|
212
|
+
return metrics
|
|
213
|
+
|
|
214
|
+
def metrics_in_group(self, group, metrics=None, sort=True):
|
|
215
|
+
"""
|
|
216
|
+
Given a group, return the metrics belonging to this group,
|
|
217
|
+
in display order.
|
|
218
|
+
"""
|
|
219
|
+
if metrics is None:
|
|
220
|
+
metrics = self.metrics
|
|
221
|
+
metrics = metrics[np.where(metrics["display_group"] == group)]
|
|
222
|
+
if sort:
|
|
223
|
+
metrics = self.sort_metrics(metrics)
|
|
224
|
+
return metrics
|
|
225
|
+
|
|
226
|
+
def metrics_in_subgroup(self, group, subgroup, metrics=None):
|
|
227
|
+
"""
|
|
228
|
+
Given a group and subgroup, return a dataframe of the metrics
|
|
229
|
+
belonging to these group/subgroups, in display order.
|
|
230
|
+
|
|
231
|
+
If 'metrics' is provided, then only consider this subset of metrics.
|
|
232
|
+
"""
|
|
233
|
+
metrics = self.metrics_in_group(group, metrics, sort=False)
|
|
234
|
+
if len(metrics) > 0:
|
|
235
|
+
metrics = metrics[np.where(metrics["display_subgroup"] == subgroup)]
|
|
236
|
+
metrics = self.sort_metrics(metrics)
|
|
237
|
+
return metrics
|
|
238
|
+
|
|
239
|
+
def metrics_to_subgroups(self, metrics):
|
|
240
|
+
"""
|
|
241
|
+
Given an array of metrics, return an ordered dict of their
|
|
242
|
+
group/subgroups.
|
|
243
|
+
"""
|
|
244
|
+
group_list = sorted(np.unique(metrics["display_group"]))
|
|
245
|
+
groups = OrderedDict()
|
|
246
|
+
for group in group_list:
|
|
247
|
+
groupmetrics = self.metrics_in_group(group, metrics, sort=False)
|
|
248
|
+
groups[group] = sorted(np.unique(groupmetrics["display_subgroup"]))
|
|
249
|
+
return groups
|
|
250
|
+
|
|
251
|
+
def metrics_with_plot_type(self, plot_type="SkyMap", metrics=None):
|
|
252
|
+
"""
|
|
253
|
+
Return an array of metrics with plot=plot_type
|
|
254
|
+
(optionally also within a metric subset).
|
|
255
|
+
"""
|
|
256
|
+
# Allow some variation in plot_type names for backward compatibility,
|
|
257
|
+
# even if plot_type is a list.
|
|
258
|
+
if not isinstance(plot_type, list):
|
|
259
|
+
plot_type = [plot_type]
|
|
260
|
+
plot_types = []
|
|
261
|
+
for p_t in plot_type:
|
|
262
|
+
plot_types.append(p_t)
|
|
263
|
+
if p_t.endswith("lot"):
|
|
264
|
+
plot_types.append(p_t[:-4])
|
|
265
|
+
else:
|
|
266
|
+
plot_types.append(p_t.lower() + "Plot")
|
|
267
|
+
if metrics is None:
|
|
268
|
+
metrics = self.metrics
|
|
269
|
+
# Identify the plots with the right plot_type, get their IDs.
|
|
270
|
+
plot_match = self.plots[np.isin(self.plots["plot_type"], plot_types)]
|
|
271
|
+
# Convert those potentially matching metricIds to metrics,
|
|
272
|
+
# using the subset info.
|
|
273
|
+
metrics = self.metric_ids_to_metrics(plot_match["metric_id"], metrics)
|
|
274
|
+
return metrics
|
|
275
|
+
|
|
276
|
+
def unique_metric_names(self, metrics=None, baseonly=True):
|
|
277
|
+
"""
|
|
278
|
+
Return a list of the unique metric names,
|
|
279
|
+
preserving the order of 'metrics'.
|
|
280
|
+
"""
|
|
281
|
+
if metrics is None:
|
|
282
|
+
metrics = self.metrics
|
|
283
|
+
if baseonly:
|
|
284
|
+
sort_name = "base_metric_name"
|
|
285
|
+
else:
|
|
286
|
+
sort_name = "metric_name"
|
|
287
|
+
metric_names = list(np.unique(metrics[sort_name]))
|
|
288
|
+
return metric_names
|
|
289
|
+
|
|
290
|
+
def metrics_with_summary_stat(self, summary_stat_name="Identity", metrics=None):
|
|
291
|
+
"""
|
|
292
|
+
Return metrics with summary stat matching 'summary_stat_name'
|
|
293
|
+
(optionally, within a metric subset).
|
|
294
|
+
"""
|
|
295
|
+
if metrics is None:
|
|
296
|
+
metrics = self.metrics
|
|
297
|
+
# Identify the potentially matching stats.
|
|
298
|
+
stats = self.stats[np.isin(self.stats["summary_metric"], summary_stat_name)]
|
|
299
|
+
# Identify the subset of relevant metrics.
|
|
300
|
+
metrics = self.metric_ids_to_metrics(stats["metric_id"], metrics)
|
|
301
|
+
# Re-sort metrics because at this point, probably want displayOrder
|
|
302
|
+
# + info_label before metric name.
|
|
303
|
+
metrics = self.sort_metrics(
|
|
304
|
+
metrics,
|
|
305
|
+
order=[
|
|
306
|
+
"display_group",
|
|
307
|
+
"display_subgroup",
|
|
308
|
+
"slicer_name",
|
|
309
|
+
"display_order",
|
|
310
|
+
"metric_info_label",
|
|
311
|
+
"base_metric_name",
|
|
312
|
+
],
|
|
313
|
+
)
|
|
314
|
+
return metrics
|
|
315
|
+
|
|
316
|
+
def metrics_with_stats(self, metrics=None):
|
|
317
|
+
"""
|
|
318
|
+
Return metrics that have any summary stat.
|
|
319
|
+
"""
|
|
320
|
+
if metrics is None:
|
|
321
|
+
metrics = self.metrics
|
|
322
|
+
# Identify metricIds which are also in stats.
|
|
323
|
+
metrics = metrics[np.isin(metrics["metric_id"], self.stats["metric_id"])]
|
|
324
|
+
metrics = self.sort_metrics(
|
|
325
|
+
metrics,
|
|
326
|
+
order=[
|
|
327
|
+
"display_group",
|
|
328
|
+
"display_subgroup",
|
|
329
|
+
"slicer_name",
|
|
330
|
+
"display_order",
|
|
331
|
+
"metric_info_label",
|
|
332
|
+
"base_metric_name",
|
|
333
|
+
],
|
|
334
|
+
)
|
|
335
|
+
return metrics
|
|
336
|
+
|
|
337
|
+
def unique_slicer_names(self, metrics=None):
|
|
338
|
+
"""
|
|
339
|
+
For an array of metrics, return the unique slicer names.
|
|
340
|
+
"""
|
|
341
|
+
if metrics is None:
|
|
342
|
+
metrics = self.metrics
|
|
343
|
+
return list(np.unique(metrics["slicer_name"]))
|
|
344
|
+
|
|
345
|
+
def metrics_with_slicer(self, slicer, metrics=None):
|
|
346
|
+
"""
|
|
347
|
+
For an array of metrics, return the subset which match a
|
|
348
|
+
particular 'slicername' value.
|
|
349
|
+
"""
|
|
350
|
+
if metrics is None:
|
|
351
|
+
metrics = self.metrics
|
|
352
|
+
metrics = metrics[np.where(metrics["slicer_name"] == slicer)]
|
|
353
|
+
return metrics
|
|
354
|
+
|
|
355
|
+
def unique_metric_name_and_info_label(self, metrics=None):
|
|
356
|
+
"""
|
|
357
|
+
For an array of metrics, return the unique metric names
|
|
358
|
+
+ info_label combo in same order.
|
|
359
|
+
"""
|
|
360
|
+
if metrics is None:
|
|
361
|
+
metrics = self.metrics
|
|
362
|
+
metric_info_label = []
|
|
363
|
+
for metric_name, info_label in zip(metrics["metric_name"], metrics["metric_info_label"]):
|
|
364
|
+
metricinfo = " ".join([metric_name, info_label])
|
|
365
|
+
if metricinfo not in metric_info_label:
|
|
366
|
+
metric_info_label.append(metricinfo)
|
|
367
|
+
return metric_info_label
|
|
368
|
+
|
|
369
|
+
def unique_metric_info_label(self, metrics=None):
|
|
370
|
+
"""
|
|
371
|
+
For an array of metrics, return a list of the unique info_label.
|
|
372
|
+
"""
|
|
373
|
+
if metrics is None:
|
|
374
|
+
metrics = self.metrics
|
|
375
|
+
return list(np.unique(metrics["metric_info_label"]))
|
|
376
|
+
|
|
377
|
+
def metrics_with_info_label(self, info_label, metrics=None):
|
|
378
|
+
"""
|
|
379
|
+
For an array of metrics, return the subset which match a
|
|
380
|
+
particular 'info_label' value.
|
|
381
|
+
"""
|
|
382
|
+
if metrics is None:
|
|
383
|
+
metrics = self.metrics
|
|
384
|
+
metrics = metrics[np.where(metrics["metric_info_label"] == info_label)]
|
|
385
|
+
return metrics
|
|
386
|
+
|
|
387
|
+
def metrics_with_metric_name(self, metric_name, metrics=None, baseonly=True):
|
|
388
|
+
"""
|
|
389
|
+
Return all metrics which match metric_name
|
|
390
|
+
(default, only the 'base' metric name).
|
|
391
|
+
"""
|
|
392
|
+
if metrics is None:
|
|
393
|
+
metrics = self.metrics
|
|
394
|
+
if baseonly:
|
|
395
|
+
metrics = metrics[np.where(metrics["base_metric_name"] == metric_name)]
|
|
396
|
+
else:
|
|
397
|
+
metrics = metrics[np.where(metrics["metric_name"] == metric_name)]
|
|
398
|
+
return metrics
|
|
399
|
+
|
|
400
|
+
def metric_info(self, metric=None, with_data_link=False, with_slicer_name=True):
|
|
401
|
+
"""
|
|
402
|
+
Return a dict with the metric info we want to show on the webpages.
|
|
403
|
+
|
|
404
|
+
Currently : MetricName / Slicer/ InfoLabel / datafile (for download)
|
|
405
|
+
Used to build a lot of tables in showMaf.
|
|
406
|
+
"""
|
|
407
|
+
metric_info = OrderedDict()
|
|
408
|
+
if metric is None:
|
|
409
|
+
metric_info["Metric Name"] = ""
|
|
410
|
+
if with_slicer_name:
|
|
411
|
+
metric_info["Slicer"] = ""
|
|
412
|
+
metric_info["Info Label"] = ""
|
|
413
|
+
if with_data_link:
|
|
414
|
+
metric_info["Data"] = []
|
|
415
|
+
metric_info["Data"].append([None, None])
|
|
416
|
+
return metric_info
|
|
417
|
+
# Otherwise, do this for real (not a blank).
|
|
418
|
+
metric_info["Metric Name"] = metric["metric_name"]
|
|
419
|
+
if with_slicer_name:
|
|
420
|
+
metric_info["Slicer"] = metric["slicer_name"]
|
|
421
|
+
metric_info["InfoL abel"] = metric["metric_info_label"]
|
|
422
|
+
if with_data_link:
|
|
423
|
+
metric_info["Data"] = []
|
|
424
|
+
metric_info["Data"].append(metric["metric_datafile"])
|
|
425
|
+
metric_info["Data"].append(os.path.join(self.out_dir, metric["metric_datafile"]))
|
|
426
|
+
return metric_info
|
|
427
|
+
|
|
428
|
+
def caption_for_metric(self, metric):
|
|
429
|
+
"""
|
|
430
|
+
Return the caption for a given metric.
|
|
431
|
+
"""
|
|
432
|
+
caption = metric["display_caption"]
|
|
433
|
+
if caption == "NULL":
|
|
434
|
+
return ""
|
|
435
|
+
else:
|
|
436
|
+
return caption
|
|
437
|
+
|
|
438
|
+
# Methods for plots.
|
|
439
|
+
|
|
440
|
+
def plots_for_metric(self, metric):
|
|
441
|
+
"""
|
|
442
|
+
Return a numpy array of the plots which match a given metric.
|
|
443
|
+
"""
|
|
444
|
+
return self.plots[np.where(self.plots["metric_id"] == metric["metric_id"])]
|
|
445
|
+
|
|
446
|
+
def plot_dict(self, plots=None):
|
|
447
|
+
"""
|
|
448
|
+
Given an array of plots (for a single metric usually).
|
|
449
|
+
Returns an ordered dict with 'plot_type' for interfacing with
|
|
450
|
+
jinja2 templates.
|
|
451
|
+
plot_dict ==
|
|
452
|
+
{'SkyMap': {'plot_file': [], 'thumb_file', []}, 'Histogram': {}..}
|
|
453
|
+
|
|
454
|
+
If no plot of a particular type, the plot_file and thumb_file
|
|
455
|
+
are empty lists.
|
|
456
|
+
Calling with plots=None returns a blank plot_dict.
|
|
457
|
+
"""
|
|
458
|
+
plot_dict = OrderedDict()
|
|
459
|
+
# Go through plots in 'plotOrder'.
|
|
460
|
+
if plots is None:
|
|
461
|
+
for p in self.plot_order:
|
|
462
|
+
plot_dict[p] = {}
|
|
463
|
+
plot_dict[p]["plot_file"] = ""
|
|
464
|
+
plot_dict[p]["thumb_file"] = ""
|
|
465
|
+
else:
|
|
466
|
+
plot_types = list(np.unique(plots["plot_type"]))
|
|
467
|
+
for p in self.plot_order:
|
|
468
|
+
if p in plot_types:
|
|
469
|
+
plot_dict[p] = {}
|
|
470
|
+
plotmatch = plots[np.where(plots["plot_type"] == p)]
|
|
471
|
+
plot_dict[p]["plot_file"] = []
|
|
472
|
+
plot_dict[p]["thumb_file"] = []
|
|
473
|
+
for pm in plotmatch:
|
|
474
|
+
plot_dict[p]["plot_file"].append(self.get_plot_file(pm))
|
|
475
|
+
plot_dict[p]["thumb_file"].append(self.get_thumb_file(pm))
|
|
476
|
+
plot_types.remove(p)
|
|
477
|
+
# Round up remaining plots.
|
|
478
|
+
for p in plot_types:
|
|
479
|
+
plot_dict[p] = {}
|
|
480
|
+
plotmatch = plots[np.where(plots["plot_type"] == p)]
|
|
481
|
+
plot_dict[p]["plot_file"] = []
|
|
482
|
+
plot_dict[p]["thumb_file"] = []
|
|
483
|
+
for pm in plotmatch:
|
|
484
|
+
plot_dict[p]["plot_file"].append(self.get_plot_file(pm))
|
|
485
|
+
plot_dict[p]["thumb_file"].append(self.get_thumb_file(pm))
|
|
486
|
+
return plot_dict
|
|
487
|
+
|
|
488
|
+
def get_thumb_file(self, plot):
|
|
489
|
+
"""
|
|
490
|
+
Return the thumbnail file name for a given plot.
|
|
491
|
+
"""
|
|
492
|
+
thumb_file = os.path.join(self.out_dir, plot["thumb_file"])
|
|
493
|
+
return thumb_file
|
|
494
|
+
|
|
495
|
+
def get_plot_file(self, plot):
|
|
496
|
+
"""
|
|
497
|
+
Return the filename for a given plot.
|
|
498
|
+
"""
|
|
499
|
+
plot_file = os.path.join(self.out_dir, plot["plot_file"])
|
|
500
|
+
return plot_file
|
|
501
|
+
|
|
502
|
+
def order_plots(self, sky_plots):
|
|
503
|
+
"""
|
|
504
|
+
sky_plots = numpy array of skymap plots.
|
|
505
|
+
|
|
506
|
+
Returns an ordered list of plotDicts.
|
|
507
|
+
|
|
508
|
+
The goal is to lay out the skymaps in a 3x2 grid on the MultiColor
|
|
509
|
+
page, in ugrizy order.
|
|
510
|
+
If a plot for a filter is missing, add a gap. (i.e. if there is no
|
|
511
|
+
u band plot, keep a blank spot).
|
|
512
|
+
If there are other plots, with multiple filters or no filter
|
|
513
|
+
info, they are added to the end.
|
|
514
|
+
If sky_plots includes multiple plots in the same filter,
|
|
515
|
+
just goes back to displayOrder.
|
|
516
|
+
"""
|
|
517
|
+
ordered_sky_plots = []
|
|
518
|
+
if len(sky_plots) == 0:
|
|
519
|
+
return ordered_sky_plots
|
|
520
|
+
|
|
521
|
+
order_list = ["u", "g", "r", "i", "z", "y"]
|
|
522
|
+
blank_plot_dict = self.plot_dict(None)
|
|
523
|
+
|
|
524
|
+
# Look for filter names in the plot filenames.
|
|
525
|
+
too_many_plots = False
|
|
526
|
+
for f in order_list:
|
|
527
|
+
pattern = "_" + f + "_"
|
|
528
|
+
matches = np.array([bool(re.search(pattern, x)) for x in sky_plots["plot_file"]])
|
|
529
|
+
match_sky_plot = sky_plots[matches]
|
|
530
|
+
if len(match_sky_plot) == 1:
|
|
531
|
+
ordered_sky_plots.append(self.plot_dict(match_sky_plot))
|
|
532
|
+
elif len(match_sky_plot) == 0:
|
|
533
|
+
ordered_sky_plots.append(blank_plot_dict)
|
|
534
|
+
else:
|
|
535
|
+
# If we found more than one plot in the same filter,
|
|
536
|
+
# we just go back to displayOrder.
|
|
537
|
+
too_many_plots = True
|
|
538
|
+
break
|
|
539
|
+
|
|
540
|
+
if too_many_plots is False:
|
|
541
|
+
# Add on any additional non-filter plots (e.g. joint completeness)
|
|
542
|
+
# that do NOT match original _*_ pattern.
|
|
543
|
+
pattern = "_[ugrizy]_"
|
|
544
|
+
nonmatches = np.array([bool(re.search(pattern, x)) for x in sky_plots["plot_file"]])
|
|
545
|
+
nonmatch_sky_plots = sky_plots[~nonmatches]
|
|
546
|
+
if len(nonmatch_sky_plots) > 0:
|
|
547
|
+
for sky_plot in nonmatch_sky_plots:
|
|
548
|
+
ordered_sky_plots.append(self.plot_dict(np.array([sky_plot])))
|
|
549
|
+
|
|
550
|
+
elif too_many_plots:
|
|
551
|
+
metrics = self.metrics[np.isin(self.metrics["metric_id"], sky_plots["metric_id"])]
|
|
552
|
+
metrics = self.sort_metrics(metrics, order=["display_order"])
|
|
553
|
+
ordered_sky_plots = []
|
|
554
|
+
for m in metrics:
|
|
555
|
+
sky_plot = sky_plots[np.where(sky_plots["metric_id"] == m["metric_id"])]
|
|
556
|
+
ordered_sky_plots.append(self.plot_dict(sky_plot))
|
|
557
|
+
|
|
558
|
+
# Pad out to make sure there are rows of 3
|
|
559
|
+
while len(ordered_sky_plots) % 3 != 0:
|
|
560
|
+
ordered_sky_plots.append(blank_plot_dict)
|
|
561
|
+
|
|
562
|
+
return ordered_sky_plots
|
|
563
|
+
|
|
564
|
+
def get_sky_maps(self, metrics=None, plot_type="SkyMap"):
|
|
565
|
+
"""
|
|
566
|
+
Return a numpy array of the plots with plot_type=plot_type,
|
|
567
|
+
optionally for subset of metrics.
|
|
568
|
+
"""
|
|
569
|
+
if metrics is None:
|
|
570
|
+
metrics = self.metrics
|
|
571
|
+
# Match the plots to the metrics required.
|
|
572
|
+
plot_metric_match = self.plots[np.isin(self.plots["metric_id"], metrics["metric_id"])]
|
|
573
|
+
# Match the plot type (which could be a list)
|
|
574
|
+
plot_match = plot_metric_match[np.isin(plot_metric_match["plot_type"], plot_type)]
|
|
575
|
+
return plot_match
|
|
576
|
+
|
|
577
|
+
# Set of methods to deal with summary stats.
|
|
578
|
+
|
|
579
|
+
def stats_for_metric(self, metric, stat_name=None):
|
|
580
|
+
"""
|
|
581
|
+
Return a numpy array of summary statistics which match a
|
|
582
|
+
given metric(s).
|
|
583
|
+
|
|
584
|
+
Optionally specify a particular stat_name that you want to match.
|
|
585
|
+
"""
|
|
586
|
+
stats = self.stats[np.where(self.stats["metric_id"] == metric["metric_id"])]
|
|
587
|
+
if stat_name is not None:
|
|
588
|
+
stats = stats[np.where(stats["summary_metric"] == stat_name)]
|
|
589
|
+
return stats
|
|
590
|
+
|
|
591
|
+
def stat_dict(self, stats):
|
|
592
|
+
"""
|
|
593
|
+
Returns an ordered dictionary with statName:statValue
|
|
594
|
+
for an array of stats.
|
|
595
|
+
|
|
596
|
+
Note that if you pass 'stats' from multiple metrics with the same
|
|
597
|
+
summary names, they will be overwritten in the resulting dictionary!
|
|
598
|
+
So just use stats from one metric, with unique summary_metric names.
|
|
599
|
+
"""
|
|
600
|
+
# Result = dict with key
|
|
601
|
+
# == summary stat name, value = summary stat value.
|
|
602
|
+
sdict = OrderedDict()
|
|
603
|
+
statnames = self.order_stat_names(stats)
|
|
604
|
+
for n in statnames:
|
|
605
|
+
match = stats[np.where(stats["summary_metric"] == n)]
|
|
606
|
+
# We're only going to look at the first value;
|
|
607
|
+
# and this should be a float.
|
|
608
|
+
sdict[n] = match["summary_value"][0]
|
|
609
|
+
return sdict
|
|
610
|
+
|
|
611
|
+
def order_stat_names(self, stats):
|
|
612
|
+
"""
|
|
613
|
+
Given an array of stats, return a list containing all the unique
|
|
614
|
+
'summary_metric' names in a default ordering
|
|
615
|
+
(identity-count-mean-median-rms..).
|
|
616
|
+
"""
|
|
617
|
+
names = list(np.unique(stats["summary_metric"]))
|
|
618
|
+
# Add some default sorting:
|
|
619
|
+
namelist = []
|
|
620
|
+
for nord in self.summary_stat_order:
|
|
621
|
+
if nord in names:
|
|
622
|
+
namelist.append(nord)
|
|
623
|
+
names.remove(nord)
|
|
624
|
+
for remaining in names:
|
|
625
|
+
namelist.append(remaining)
|
|
626
|
+
return namelist
|
|
627
|
+
|
|
628
|
+
def all_stat_names(self, metrics):
|
|
629
|
+
"""
|
|
630
|
+
Given an array of metrics, return a list containing all the
|
|
631
|
+
unique 'summary_metric' names in a default ordering.
|
|
632
|
+
"""
|
|
633
|
+
names = np.unique(
|
|
634
|
+
self.stats["summary_metric"][np.isin(self.stats["metric_id"], metrics["metric_id"])]
|
|
635
|
+
)
|
|
636
|
+
names = list(names)
|
|
637
|
+
# Add some default sorting.
|
|
638
|
+
namelist = []
|
|
639
|
+
for nord in self.summary_stat_order:
|
|
640
|
+
if nord in names:
|
|
641
|
+
namelist.append(nord)
|
|
642
|
+
names.remove(nord)
|
|
643
|
+
for remaining in names:
|
|
644
|
+
namelist.append(remaining)
|
|
645
|
+
return namelist
|