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.
Files changed (387) hide show
  1. batch/compile_prenight_metadata_cache.sh +34 -0
  2. batch/run_auxtel_prenight_sims.sh +163 -0
  3. batch/run_prenight_sims.sh +239 -0
  4. docs/.gitignore +3 -0
  5. docs/Makefile +32 -0
  6. docs/api.rst +25 -0
  7. docs/conf.py +8 -0
  8. docs/data-api.rst +12 -0
  9. docs/data-download.rst +70 -0
  10. docs/developer.rst +14 -0
  11. docs/documenteer.toml +11 -0
  12. docs/index.rst +22 -0
  13. docs/installation.rst +76 -0
  14. docs/introduction.rst +37 -0
  15. docs/maf-api-batches.rst +12 -0
  16. docs/maf-api-db.rst +12 -0
  17. docs/maf-api-maf-contrib.rst +12 -0
  18. docs/maf-api-maps.rst +12 -0
  19. docs/maf-api-metricbundles.rst +12 -0
  20. docs/maf-api-metrics.rst +12 -0
  21. docs/maf-api-plots.rst +12 -0
  22. docs/maf-api-run-comparison.rst +12 -0
  23. docs/maf-api-slicers.rst +12 -0
  24. docs/maf-api-stackers.rst +12 -0
  25. docs/maf-api-utils.rst +12 -0
  26. docs/maf-api.rst +22 -0
  27. docs/maf.rst +60 -0
  28. docs/metric_list.py +49 -0
  29. docs/moving-objects-api.rst +12 -0
  30. docs/moving-objects.rst +22 -0
  31. docs/phot-utils-api.rst +12 -0
  32. docs/phot-utils.rst +11 -0
  33. docs/prenight.rst +117 -0
  34. docs/protoarchive.rst +276 -0
  35. docs/satellite-constellations-api.rst +12 -0
  36. docs/satellite-constellations.rst +13 -0
  37. docs/selfcal-api.rst +12 -0
  38. docs/selfcal.rst +15 -0
  39. docs/sim-archive-api.rst +12 -0
  40. docs/skybrightness-api.rst +12 -0
  41. docs/skybrightness.rst +23 -0
  42. docs/user-guide.rst +28 -0
  43. docs/vseqarchive-architecture.rst +438 -0
  44. docs/vseqarchive-setup.rst +238 -0
  45. docs/vseqarchive.rst +225 -0
  46. rubin_sim/__init__.py +7 -0
  47. rubin_sim/data/__init__.py +1 -0
  48. rubin_sim/data/rs_download_data.py +155 -0
  49. rubin_sim/maf/__init__.py +34 -0
  50. rubin_sim/maf/batches/__init__.py +18 -0
  51. rubin_sim/maf/batches/altaz_batch.py +161 -0
  52. rubin_sim/maf/batches/col_map_dict.py +274 -0
  53. rubin_sim/maf/batches/common.py +388 -0
  54. rubin_sim/maf/batches/ddf_batch.py +728 -0
  55. rubin_sim/maf/batches/filterchange_batch.py +182 -0
  56. rubin_sim/maf/batches/glance_batch.py +591 -0
  57. rubin_sim/maf/batches/hourglass_batch.py +79 -0
  58. rubin_sim/maf/batches/info_batch.py +114 -0
  59. rubin_sim/maf/batches/metadata_batch.py +558 -0
  60. rubin_sim/maf/batches/moving_objects_batch.py +1587 -0
  61. rubin_sim/maf/batches/openshutter_batch.py +100 -0
  62. rubin_sim/maf/batches/radar_limited.py +1100 -0
  63. rubin_sim/maf/batches/science_radar_batch.py +1910 -0
  64. rubin_sim/maf/batches/skycoverage.py +155 -0
  65. rubin_sim/maf/batches/slew_batch.py +146 -0
  66. rubin_sim/maf/batches/srd_batch.py +637 -0
  67. rubin_sim/maf/batches/time_batch.py +757 -0
  68. rubin_sim/maf/batches/time_sci_batch.py +105 -0
  69. rubin_sim/maf/batches/visitdepth_batch.py +485 -0
  70. rubin_sim/maf/db/__init__.py +2 -0
  71. rubin_sim/maf/db/add_run.py +34 -0
  72. rubin_sim/maf/db/results_db.py +1074 -0
  73. rubin_sim/maf/db/tracking_db.py +332 -0
  74. rubin_sim/maf/ddf_dir.py +53 -0
  75. rubin_sim/maf/generate_ss.py +218 -0
  76. rubin_sim/maf/glance_dir.py +58 -0
  77. rubin_sim/maf/maf_contrib/__init__.py +25 -0
  78. rubin_sim/maf/maf_contrib/calculate_lsst_field_visibility_astropy.py +170 -0
  79. rubin_sim/maf/maf_contrib/depth_limited_num_gal_metric.py +109 -0
  80. rubin_sim/maf/maf_contrib/example_new_metrics.py +40 -0
  81. rubin_sim/maf/maf_contrib/filter_pair_t_gaps_metric.py +208 -0
  82. rubin_sim/maf/maf_contrib/grb_transient_metric.py +249 -0
  83. rubin_sim/maf/maf_contrib/gw170817_det_metric.py +72 -0
  84. rubin_sim/maf/maf_contrib/intervals_between_obs_metric.py +68 -0
  85. rubin_sim/maf/maf_contrib/kne_metrics.py +473 -0
  86. rubin_sim/maf/maf_contrib/lss_metrics.py +45 -0
  87. rubin_sim/maf/maf_contrib/lss_obs_strategy/__init__.py +3 -0
  88. rubin_sim/maf/maf_contrib/lss_obs_strategy/constants_for_pipeline.py +73 -0
  89. rubin_sim/maf/maf_contrib/lss_obs_strategy/galaxy_counts_metric_extended.py +205 -0
  90. rubin_sim/maf/maf_contrib/lss_obs_strategy/galaxy_counts_with_pixel_calibration.py +171 -0
  91. rubin_sim/maf/maf_contrib/lv_dwarfs/__init__.py +1 -0
  92. rubin_sim/maf/maf_contrib/lv_dwarfs/lv_dwarfs_metrics.py +388 -0
  93. rubin_sim/maf/maf_contrib/microlensing_metric.py +593 -0
  94. rubin_sim/maf/maf_contrib/num_obs_in_survey_time_overlap_metric.py +43 -0
  95. rubin_sim/maf/maf_contrib/periodic_metric.py +51 -0
  96. rubin_sim/maf/maf_contrib/periodic_star_metric.py +186 -0
  97. rubin_sim/maf/maf_contrib/periodic_star_modulation_metric.py +236 -0
  98. rubin_sim/maf/maf_contrib/presto_color_kne_pop_metric.py +441 -0
  99. rubin_sim/maf/maf_contrib/selfcal_uniformity_metric.py +171 -0
  100. rubin_sim/maf/maf_contrib/star_count_mass_metric.py +64 -0
  101. rubin_sim/maf/maf_contrib/star_count_metric.py +56 -0
  102. rubin_sim/maf/maf_contrib/star_counts/__init__.py +8 -0
  103. rubin_sim/maf/maf_contrib/star_counts/abs_mag.py +324 -0
  104. rubin_sim/maf/maf_contrib/star_counts/coords.py +99 -0
  105. rubin_sim/maf/maf_contrib/star_counts/readme.txt +1 -0
  106. rubin_sim/maf/maf_contrib/star_counts/spec_type.py +91 -0
  107. rubin_sim/maf/maf_contrib/star_counts/starcount.py +30 -0
  108. rubin_sim/maf/maf_contrib/star_counts/starcount_bymass.py +93 -0
  109. rubin_sim/maf/maf_contrib/star_counts/stellardensity.py +59 -0
  110. rubin_sim/maf/maf_contrib/static_probes_fom_summary_metric.py +386 -0
  111. rubin_sim/maf/maf_contrib/tdes_pop_metric.py +362 -0
  112. rubin_sim/maf/maf_contrib/transient_ascii_sed_metric.py +652 -0
  113. rubin_sim/maf/maf_contrib/triplet_metric.py +156 -0
  114. rubin_sim/maf/maf_contrib/var_depth_metric.py +157 -0
  115. rubin_sim/maf/maf_contrib/xrb_metrics.py +523 -0
  116. rubin_sim/maf/maf_contrib/young_stellar_objects_metric.py +200 -0
  117. rubin_sim/maf/maf_night_report.py +200 -0
  118. rubin_sim/maf/make_fbs_tracking_db.py +90 -0
  119. rubin_sim/maf/maps/__init__.py +8 -0
  120. rubin_sim/maf/maps/base_map.py +72 -0
  121. rubin_sim/maf/maps/create_gaia_density_map.py +158 -0
  122. rubin_sim/maf/maps/dust_map.py +66 -0
  123. rubin_sim/maf/maps/dust_map_3d.py +190 -0
  124. rubin_sim/maf/maps/ebv_3d_hp.py +170 -0
  125. rubin_sim/maf/maps/ebv_hp.py +64 -0
  126. rubin_sim/maf/maps/gal_coords_map.py +22 -0
  127. rubin_sim/maf/maps/galactic_plane_priority_maps.py +210 -0
  128. rubin_sim/maf/maps/stellar_density_map.py +73 -0
  129. rubin_sim/maf/maps/trilegal_map.py +82 -0
  130. rubin_sim/maf/metadata_dir.py +90 -0
  131. rubin_sim/maf/metric_bundles/__init__.py +3 -0
  132. rubin_sim/maf/metric_bundles/metric_bundle.py +816 -0
  133. rubin_sim/maf/metric_bundles/metric_bundle_group.py +834 -0
  134. rubin_sim/maf/metric_bundles/mo_metric_bundle.py +646 -0
  135. rubin_sim/maf/metrics/__init__.py +52 -0
  136. rubin_sim/maf/metrics/agn_time_lag_metric.py +118 -0
  137. rubin_sim/maf/metrics/agnstructure.py +141 -0
  138. rubin_sim/maf/metrics/area_summary_metrics.py +120 -0
  139. rubin_sim/maf/metrics/base_metric.py +215 -0
  140. rubin_sim/maf/metrics/brown_dwarf_metric.py +162 -0
  141. rubin_sim/maf/metrics/cadence_metrics.py +400 -0
  142. rubin_sim/maf/metrics/calibration_metrics.py +618 -0
  143. rubin_sim/maf/metrics/chip_vendor_metric.py +43 -0
  144. rubin_sim/maf/metrics/color_slope_metrics.py +189 -0
  145. rubin_sim/maf/metrics/cosmology_summary_metrics.py +1212 -0
  146. rubin_sim/maf/metrics/coverage_metric.py +48 -0
  147. rubin_sim/maf/metrics/crowding_metric.py +255 -0
  148. rubin_sim/maf/metrics/cumulative_metric.py +46 -0
  149. rubin_sim/maf/metrics/dcr_metric.py +93 -0
  150. rubin_sim/maf/metrics/exgal_m5.py +57 -0
  151. rubin_sim/maf/metrics/fft_metric.py +27 -0
  152. rubin_sim/maf/metrics/galactic_plane_metrics.py +375 -0
  153. rubin_sim/maf/metrics/galplane_time_sampling_metrics.py +236 -0
  154. rubin_sim/maf/metrics/hourglass_metric.py +130 -0
  155. rubin_sim/maf/metrics/incremental_template_metric.py +255 -0
  156. rubin_sim/maf/metrics/kuiper_metrics.py +26 -0
  157. rubin_sim/maf/metrics/mo_metrics.py +1496 -0
  158. rubin_sim/maf/metrics/mo_summary_metrics.py +464 -0
  159. rubin_sim/maf/metrics/night_pointing_metric.py +70 -0
  160. rubin_sim/maf/metrics/optimal_m5_metric.py +94 -0
  161. rubin_sim/maf/metrics/pair_metric.py +69 -0
  162. rubin_sim/maf/metrics/periodic_detect_metric.py +133 -0
  163. rubin_sim/maf/metrics/phase_gap_metric.py +172 -0
  164. rubin_sim/maf/metrics/qso_number_counts_metric.py +138 -0
  165. rubin_sim/maf/metrics/scaling_metrics.py +148 -0
  166. rubin_sim/maf/metrics/schedview_metrics.py +39 -0
  167. rubin_sim/maf/metrics/season_metrics.py +344 -0
  168. rubin_sim/maf/metrics/simple_metrics.py +546 -0
  169. rubin_sim/maf/metrics/sky_sat_metric.py +18 -0
  170. rubin_sim/maf/metrics/sn_cadence_metric.py +104 -0
  171. rubin_sim/maf/metrics/sn_n_sn_metric.py +1364 -0
  172. rubin_sim/maf/metrics/sn_sl_metric.py +216 -0
  173. rubin_sim/maf/metrics/sn_snr_metric.py +715 -0
  174. rubin_sim/maf/metrics/snr_weight.py +24 -0
  175. rubin_sim/maf/metrics/star_density.py +77 -0
  176. rubin_sim/maf/metrics/string_count_metric.py +95 -0
  177. rubin_sim/maf/metrics/summary_metrics.py +201 -0
  178. rubin_sim/maf/metrics/surfb_metric.py +175 -0
  179. rubin_sim/maf/metrics/technical_metrics.py +271 -0
  180. rubin_sim/maf/metrics/tgaps.py +412 -0
  181. rubin_sim/maf/metrics/tomography_models.py +2034 -0
  182. rubin_sim/maf/metrics/transient_metrics.py +268 -0
  183. rubin_sim/maf/metrics/uniformity_metrics.py +418 -0
  184. rubin_sim/maf/metrics/use_metrics.py +55 -0
  185. rubin_sim/maf/metrics/vector_metrics.py +190 -0
  186. rubin_sim/maf/metrics/visit_groups_metric.py +341 -0
  187. rubin_sim/maf/metrics/weak_lensing_systematics_metric.py +210 -0
  188. rubin_sim/maf/plots/__init__.py +14 -0
  189. rubin_sim/maf/plots/hg_plotters.py +1117 -0
  190. rubin_sim/maf/plots/hourglass_plotters.py +120 -0
  191. rubin_sim/maf/plots/mo_plotters.py +358 -0
  192. rubin_sim/maf/plots/nd_plotters.py +220 -0
  193. rubin_sim/maf/plots/neo_distance_plotter.py +140 -0
  194. rubin_sim/maf/plots/night_pointing_plotter.py +96 -0
  195. rubin_sim/maf/plots/oned_plotters.py +114 -0
  196. rubin_sim/maf/plots/perceptual_rainbow.py +30 -0
  197. rubin_sim/maf/plots/plot_handler.py +766 -0
  198. rubin_sim/maf/plots/skyproj_plotters.py +540 -0
  199. rubin_sim/maf/plots/spatial_plotters.py +1029 -0
  200. rubin_sim/maf/plots/special_plotters.py +256 -0
  201. rubin_sim/maf/plots/two_d_plotters.py +177 -0
  202. rubin_sim/maf/plots/xyplotter.py +37 -0
  203. rubin_sim/maf/run_comparison/__init__.py +5 -0
  204. rubin_sim/maf/run_comparison/archive.py +584 -0
  205. rubin_sim/maf/run_comparison/gather_summaries.py +125 -0
  206. rubin_sim/maf/run_comparison/microlensing_compare.py +514 -0
  207. rubin_sim/maf/run_comparison/radar_plot.py +202 -0
  208. rubin_sim/maf/run_comparison/summary_plots.py +710 -0
  209. rubin_sim/maf/run_moving_calc.py +239 -0
  210. rubin_sim/maf/run_moving_fractions.py +128 -0
  211. rubin_sim/maf/run_moving_join.py +103 -0
  212. rubin_sim/maf/run_selfcal_metric.py +92 -0
  213. rubin_sim/maf/scimaf_dir.py +87 -0
  214. rubin_sim/maf/show_maf.py +227 -0
  215. rubin_sim/maf/slicers/__init__.py +13 -0
  216. rubin_sim/maf/slicers/base_slicer.py +513 -0
  217. rubin_sim/maf/slicers/base_spatial_slicer.py +202 -0
  218. rubin_sim/maf/slicers/healpix_sdss_slicer.py +118 -0
  219. rubin_sim/maf/slicers/healpix_slicer.py +189 -0
  220. rubin_sim/maf/slicers/healpix_subset_slicer.py +293 -0
  221. rubin_sim/maf/slicers/hourglass_slicer.py +37 -0
  222. rubin_sim/maf/slicers/mo_slicer.py +171 -0
  223. rubin_sim/maf/slicers/movie_slicer.py +288 -0
  224. rubin_sim/maf/slicers/nd_slicer.py +147 -0
  225. rubin_sim/maf/slicers/one_d_slicer.py +210 -0
  226. rubin_sim/maf/slicers/time_interval_slicers.py +283 -0
  227. rubin_sim/maf/slicers/uni_slicer.py +57 -0
  228. rubin_sim/maf/slicers/user_points_slicer.py +141 -0
  229. rubin_sim/maf/stackers/__init__.py +13 -0
  230. rubin_sim/maf/stackers/base_stacker.py +221 -0
  231. rubin_sim/maf/stackers/coord_stackers.py +224 -0
  232. rubin_sim/maf/stackers/date_stackers.py +192 -0
  233. rubin_sim/maf/stackers/general_stackers.py +683 -0
  234. rubin_sim/maf/stackers/get_col_info.py +104 -0
  235. rubin_sim/maf/stackers/label_stackers.py +114 -0
  236. rubin_sim/maf/stackers/m5_optimal_stacker.py +126 -0
  237. rubin_sim/maf/stackers/mo_phase.py +265 -0
  238. rubin_sim/maf/stackers/mo_stackers.py +486 -0
  239. rubin_sim/maf/stackers/n_follow_stacker.py +187 -0
  240. rubin_sim/maf/stackers/neo_dist_stacker.py +126 -0
  241. rubin_sim/maf/stackers/sdss_stackers.py +30 -0
  242. rubin_sim/maf/stackers/sn_stacker.py +152 -0
  243. rubin_sim/maf/stackers/teff_stacker.py +154 -0
  244. rubin_sim/maf/utils/__init__.py +6 -0
  245. rubin_sim/maf/utils/astrometry_utils.py +93 -0
  246. rubin_sim/maf/utils/generate_fov_map.py +58 -0
  247. rubin_sim/maf/utils/get_date_version.py +28 -0
  248. rubin_sim/maf/utils/maf_utils.py +212 -0
  249. rubin_sim/maf/utils/opsim_utils.py +259 -0
  250. rubin_sim/maf/utils/output_utils.py +34 -0
  251. rubin_sim/maf/utils/sn_n_sn_utils.py +894 -0
  252. rubin_sim/maf/utils/sn_utils.py +369 -0
  253. rubin_sim/maf/utils/stellar_mags.py +197 -0
  254. rubin_sim/maf/web/__init__.py +2 -0
  255. rubin_sim/maf/web/favicon.ico +0 -0
  256. rubin_sim/maf/web/maf_run_results.py +645 -0
  257. rubin_sim/maf/web/maf_tracking.py +139 -0
  258. rubin_sim/maf/web/sorttable.js +496 -0
  259. rubin_sim/maf/web/templates/allmetricresults.html +72 -0
  260. rubin_sim/maf/web/templates/configs.html +28 -0
  261. rubin_sim/maf/web/templates/macros.html +243 -0
  262. rubin_sim/maf/web/templates/master.html +294 -0
  263. rubin_sim/maf/web/templates/metricselect.html +91 -0
  264. rubin_sim/maf/web/templates/multicolor.html +147 -0
  265. rubin_sim/maf/web/templates/results.html +82 -0
  266. rubin_sim/maf/web/templates/runselect.html +58 -0
  267. rubin_sim/maf/web/templates/stats.html +50 -0
  268. rubin_sim/moving_objects/__init__.py +8 -0
  269. rubin_sim/moving_objects/base_obs.py +468 -0
  270. rubin_sim/moving_objects/cheby_fits.py +689 -0
  271. rubin_sim/moving_objects/cheby_values.py +231 -0
  272. rubin_sim/moving_objects/chebyshev_utils.py +365 -0
  273. rubin_sim/moving_objects/direct_obs.py +376 -0
  274. rubin_sim/moving_objects/make_lsst_obs.py +282 -0
  275. rubin_sim/moving_objects/ooephemerides.py +643 -0
  276. rubin_sim/moving_objects/orbits.py +507 -0
  277. rubin_sim/moving_objects/pre_generate.py +37 -0
  278. rubin_sim/moving_objects/utils.py +61 -0
  279. rubin_sim/phot_utils/__init__.py +7 -0
  280. rubin_sim/phot_utils/bandpass.py +425 -0
  281. rubin_sim/phot_utils/photometric_parameters.py +449 -0
  282. rubin_sim/phot_utils/physical_parameters.py +50 -0
  283. rubin_sim/phot_utils/predicted_zeropoints.py +245 -0
  284. rubin_sim/phot_utils/sed.py +1773 -0
  285. rubin_sim/phot_utils/sed_utils.py +52 -0
  286. rubin_sim/phot_utils/signaltonoise.py +695 -0
  287. rubin_sim/phot_utils/spectral_resampling.py +161 -0
  288. rubin_sim/satellite_constellations/__init__.py +3 -0
  289. rubin_sim/satellite_constellations/basis_function.py +40 -0
  290. rubin_sim/satellite_constellations/model_observatory.py +157 -0
  291. rubin_sim/satellite_constellations/sat_utils.py +488 -0
  292. rubin_sim/selfcal/__init__.py +4 -0
  293. rubin_sim/selfcal/generate_catalog.py +188 -0
  294. rubin_sim/selfcal/offsets.py +119 -0
  295. rubin_sim/selfcal/solver.py +143 -0
  296. rubin_sim/selfcal/star_tools.py +42 -0
  297. rubin_sim/sim_archive/__init__.py +14 -0
  298. rubin_sim/sim_archive/conda_packages.py +65 -0
  299. rubin_sim/sim_archive/future_vsarch.py +480 -0
  300. rubin_sim/sim_archive/make_snapshot.py +255 -0
  301. rubin_sim/sim_archive/prenight.py +216 -0
  302. rubin_sim/sim_archive/prenightindex.py +229 -0
  303. rubin_sim/sim_archive/prototype.py +1029 -0
  304. rubin_sim/sim_archive/sim_archive.py +680 -0
  305. rubin_sim/sim_archive/tempdb.py +56 -0
  306. rubin_sim/sim_archive/util.py +146 -0
  307. rubin_sim/sim_archive/vseqarchive.py +965 -0
  308. rubin_sim/sim_archive/vseqmetadata.py +1721 -0
  309. rubin_sim/skybrightness/__init__.py +5 -0
  310. rubin_sim/skybrightness/allsky_db.py +93 -0
  311. rubin_sim/skybrightness/data/ESO_Spectra/eso_tools.py +505 -0
  312. rubin_sim/skybrightness/data/solarSpec/package.py +22 -0
  313. rubin_sim/skybrightness/generate_hdf5.py +243 -0
  314. rubin_sim/skybrightness/interp_components.py +798 -0
  315. rubin_sim/skybrightness/sky_model.py +771 -0
  316. rubin_sim/skybrightness/twilight_func.py +83 -0
  317. rubin_sim/skybrightness/utils.py +91 -0
  318. rubin_sim-2.6.1.dev2.dist-info/METADATA +95 -0
  319. rubin_sim-2.6.1.dev2.dist-info/RECORD +387 -0
  320. rubin_sim-2.6.1.dev2.dist-info/WHEEL +5 -0
  321. rubin_sim-2.6.1.dev2.dist-info/entry_points.txt +24 -0
  322. rubin_sim-2.6.1.dev2.dist-info/licenses/LICENSE +674 -0
  323. rubin_sim-2.6.1.dev2.dist-info/top_level.txt +5 -0
  324. sql/make_vseqmeta.sql +251 -0
  325. tests/data/test_data.py +26 -0
  326. tests/data/test_ddf_grid.py +17 -0
  327. tests/maf/test_3x2fom.py +68 -0
  328. tests/maf/test_archive.py +162 -0
  329. tests/maf/test_basemetrics.py +99 -0
  330. tests/maf/test_batchcommon.py +36 -0
  331. tests/maf/test_batches.py +159 -0
  332. tests/maf/test_cadencemetrics.py +388 -0
  333. tests/maf/test_calibrationmetrics.py +242 -0
  334. tests/maf/test_color_slopes.py +71 -0
  335. tests/maf/test_cosmology_summaries.py +20 -0
  336. tests/maf/test_gathersummaries.py +48 -0
  337. tests/maf/test_healpixslicer.py +439 -0
  338. tests/maf/test_healpixsubsetslicer.py +273 -0
  339. tests/maf/test_hgplotters.py +145 -0
  340. tests/maf/test_hourglassmetric.py +33 -0
  341. tests/maf/test_io.py +187 -0
  342. tests/maf/test_json.py +169 -0
  343. tests/maf/test_maps.py +199 -0
  344. tests/maf/test_metricbundle.py +69 -0
  345. tests/maf/test_mometrics.py +422 -0
  346. tests/maf/test_movieslicer.py +216 -0
  347. tests/maf/test_ndslicer.py +240 -0
  348. tests/maf/test_neodistanceplotter.py +41 -0
  349. tests/maf/test_onedslicer.py +245 -0
  350. tests/maf/test_opsimutils.py +80 -0
  351. tests/maf/test_plotters.py +134 -0
  352. tests/maf/test_resultsdb.py +145 -0
  353. tests/maf/test_schedviewmetrics.py +14 -0
  354. tests/maf/test_simplemetrics.py +200 -0
  355. tests/maf/test_snmetrics.py +335 -0
  356. tests/maf/test_snmetrics_nsn.py +123 -0
  357. tests/maf/test_stackers.py +423 -0
  358. tests/maf/test_stellarmags.py +50 -0
  359. tests/maf/test_stringcount.py +26 -0
  360. tests/maf/test_summary_plots.py +197 -0
  361. tests/maf/test_summarymetrics.py +82 -0
  362. tests/maf/test_technicalmetrics.py +267 -0
  363. tests/maf/test_templatemetrics.py +86 -0
  364. tests/maf/test_timeintervalslicers.py +97 -0
  365. tests/maf/test_trackingdb.py +88 -0
  366. tests/maf/test_unislicer.py +116 -0
  367. tests/maf/test_vectormetrics.py +225 -0
  368. tests/maf/test_visitgroupsmetric.py +181 -0
  369. tests/moving_objects/test_camera.py +39 -0
  370. tests/moving_objects/test_chebyfits.py +188 -0
  371. tests/moving_objects/test_chebyshevutils.py +76 -0
  372. tests/moving_objects/test_chebyvalues.py +245 -0
  373. tests/moving_objects/test_ephemerides.py +219 -0
  374. tests/moving_objects/test_orbits.py +170 -0
  375. tests/moving_objects/test_sed_data.py +61 -0
  376. tests/phot_utils/test_approximatebandpasses.py +91 -0
  377. tests/phot_utils/test_photometricparameters.py +268 -0
  378. tests/phot_utils/test_photometry.py +61 -0
  379. tests/phot_utils/test_predicted_zeropoints.py +53 -0
  380. tests/phot_utils/test_read_bandpasses.py +29 -0
  381. tests/phot_utils/test_sed.py +368 -0
  382. tests/phot_utils/test_snr.py +370 -0
  383. tests/satellite_constellations/test_satellites.py +36 -0
  384. tests/sim_archive/test_make_snapshot.py +24 -0
  385. tests/sim_archive/test_prototype_sim_archive.py +204 -0
  386. tests/sim_archive/test_vseqarchive.py +947 -0
  387. tests/skybrightness/test_skymodel.py +359 -0
@@ -0,0 +1,540 @@
1
+ import abc
2
+ import warnings
3
+ from collections import defaultdict
4
+ from numbers import Integral
5
+ from weakref import WeakKeyDictionary
6
+
7
+ import astropy.units as u
8
+ import healpy as hp
9
+ import matplotlib as mpl
10
+ import matplotlib.pyplot as plt
11
+ import numpy as np
12
+ import numpy.ma as ma
13
+ import pandas as pd
14
+ import skyproj
15
+ from astropy.coordinates import SkyCoord
16
+ from rubin_scheduler.utils import _healbin
17
+
18
+ from .plot_handler import BasePlotter, apply_zp_norm
19
+ from .spatial_plotters import set_color_lims, set_color_map
20
+
21
+
22
+ def compute_circle_points(
23
+ center_ra,
24
+ center_decl,
25
+ radius=90.0,
26
+ start_bear=0,
27
+ end_bear=360,
28
+ step=1,
29
+ ):
30
+ """Create points along a circle or arc on a sphere
31
+
32
+ Parameters
33
+ ----------
34
+ center_ra : `float`
35
+ R.A. of the center of the circle (deg.).
36
+ center_decl : `float`
37
+ Decl. of the center of the circle (deg.).
38
+ radius : float, optional
39
+ Radius of the circle (deg.), by default 90.0
40
+ start_bear : int, optional
41
+ Bearing (E. of N.) of the start of the circle (deg.), by default 0
42
+ end_bear : int, optional
43
+ Bearing (E. of N.) of the end of the circle (deg.), by default 360
44
+ step : int, optional
45
+ Spacing of the points along the circle (deg.), by default 1
46
+
47
+ Returns
48
+ -------
49
+ circle : `pandas.DataFrame`
50
+ DataFrame with points in the circle.
51
+ """
52
+ ras = []
53
+ decls = []
54
+
55
+ bearing_angles = np.arange(start_bear, end_bear + step, step) * u.deg
56
+ center_coords = SkyCoord(center_ra * u.deg, center_decl * u.deg)
57
+ circle_coords = center_coords.directional_offset_by(bearing_angles, radius * u.deg)
58
+ bearings = bearing_angles.value.tolist()
59
+ ras = circle_coords.ra.deg.tolist()
60
+ decls = circle_coords.dec.deg.tolist()
61
+
62
+ # de-normalize RA so there are no large jumps, which can
63
+ # confuse cartopy + matplotlib
64
+
65
+ previous_ra = ras[0]
66
+ for ra_index in range(1, len(ras)):
67
+ if ras[ra_index] - previous_ra > 180:
68
+ ras[ra_index] -= 360
69
+ if ras[ra_index] - previous_ra < -180:
70
+ ras[ra_index] += 360
71
+ previous_ra = ras[ra_index]
72
+
73
+ circle = pd.DataFrame(
74
+ {
75
+ "bearing": bearings,
76
+ "ra": ras,
77
+ "decl": decls,
78
+ }
79
+ ).set_index("bearing")
80
+
81
+ return circle
82
+
83
+
84
+ class SkyprojPlotter(BasePlotter, abc.ABC):
85
+ """Base class for all plotters that use the skyproj module."""
86
+
87
+ # Store a mapping between figures and existing SkyprojPlotters, but use
88
+ # weak keys so that the figure can be cleaned up by the garbage collector,
89
+ # and when it is entry in the dictionary automatically deleted.
90
+ skyproj_instances = WeakKeyDictionary()
91
+
92
+ default_decorations = ["ecliptic", "galactic_plane"]
93
+
94
+ default_colorbar_kwargs = {
95
+ "location": "bottom",
96
+ "shrink": 0.75,
97
+ "aspect": 25,
98
+ "pad": 0.1,
99
+ "orientation": "horizontal",
100
+ }
101
+
102
+ ecliptic_kwargs = {"edgecolor": "green"}
103
+ galactic_plane_kwargs = {"edgecolor": "blue"}
104
+ sun_kwargs = {"color": "yellow"}
105
+ moon_kwargs = {"color": "orange"}
106
+ horizon_kwargs = {"edgecolor": "black", "linewidth": 3}
107
+
108
+ def __init__(self):
109
+ super().__init__()
110
+ # Customize our plotters members for our new plot
111
+
112
+ self.plot_type = "Skyproj"
113
+ self.default_plot_dict = {}
114
+ self.default_plot_dict.update(
115
+ {
116
+ "subplot": 111,
117
+ "skyproj": skyproj.MollweideSkyproj,
118
+ "skyproj_kwargs": {"lon_0": 0},
119
+ "decorations": self.default_decorations,
120
+ "title": None,
121
+ "xlabel": None,
122
+ "label": None,
123
+ "labelsize": None,
124
+ "fontsize": None,
125
+ "figsize": None,
126
+ }
127
+ )
128
+ self._initialize_plot_dict({})
129
+ self.figure = None
130
+
131
+ def _initialize_plot_dict(self, user_plot_dict):
132
+ # Use a defaultdict so that everything not explicitly set return None.
133
+ def return_none():
134
+ return None
135
+
136
+ self.plot_dict = defaultdict(return_none)
137
+ self.plot_dict.update(self.default_plot_dict)
138
+ self.plot_dict.update(user_plot_dict)
139
+
140
+ def _prepare_skyproj(self, fig=None):
141
+ # Exctract elemens of plot_dict that need to be passed to plt.figure
142
+ fig_kwargs = {k: v for k, v in self.plot_dict.items() if k in ["figsize"]}
143
+
144
+ self.figure = plt.figure(**fig_kwargs) if fig is None else fig
145
+
146
+ # Normalize subplot specification,
147
+ # so that it can be set in either (single) integer form or tuple form.
148
+ # This is needed so that the same subplot set by different ways will be
149
+ # stored in the same key in the instance dictionary.
150
+ subplot_in = self.plot_dict["subplot"]
151
+ in_integral_form = isinstance(subplot_in, Integral) and len(str(subplot_in)) == 3
152
+ subplot = tuple(map(int, str(subplot_in))) if in_integral_form else tuple(subplot_in)
153
+
154
+ # If there is an existing instance of SkyprojPlotter (or one of its
155
+ # subclasses), reuse it.
156
+ # Otherwise, create a new one and store it so that it may be reused.
157
+ if self.figure not in self.skyproj_instances:
158
+ self.skyproj_instances[self.figure] = {}
159
+
160
+ if subplot in self.skyproj_instances[self.figure]:
161
+ existing_instance = self.skyproj_instances[self.figure][subplot]
162
+ assert isinstance(existing_instance, self.plot_dict["skyproj"])
163
+ self.skyproj = existing_instance
164
+ else:
165
+ # This instance of Axis will get deleted and replaced when the
166
+ # corresponding SkyPlot class is created, but this instances is
167
+ # needed so SkyPlot will put its instance in the correct relation
168
+ # with its figure.
169
+ ax = self.figure.add_subplot(*subplot)
170
+ self.skyproj = self.plot_dict["skyproj"](ax=ax, **self.plot_dict["skyproj_kwargs"])
171
+ self.skyproj_instances[self.figure][subplot] = self.skyproj
172
+
173
+ def draw_circle(self, center_ra, center_decl, radius=90, **kwargs):
174
+ """Draw a circle on the sphere.
175
+
176
+ Parameters
177
+ ----------
178
+ center_ra : `float`
179
+ R.A. of the center of the circle (deg.).
180
+ center_decl : `float`
181
+ Decl. of the center of the circle (deg.).
182
+ radius : float, optional
183
+ Radius of the circle (deg.), by default 90.0
184
+ **kwargs
185
+ Additional keyword arguments passed to
186
+ `skyproj._Skyproj.draw_polygon`.
187
+ """
188
+ points = compute_circle_points(center_ra, center_decl, radius)
189
+ self.skyproj.draw_polygon(points.ra, points.decl, **kwargs)
190
+
191
+ def draw_ecliptic(self):
192
+ """Draw the ecliptic the sphere.
193
+
194
+ Parameters
195
+ ----------
196
+ **kwargs
197
+ Keyword arguments passed to
198
+ `skyproj._Skyproj.draw_polygon`.
199
+ """
200
+ ecliptic_pole = SkyCoord(lon=0 * u.degree, lat=90 * u.degree, frame="geocentricmeanecliptic").icrs
201
+ self.draw_circle(ecliptic_pole.ra.deg, ecliptic_pole.dec.deg, **self.ecliptic_kwargs)
202
+
203
+ def draw_galactic_plane(self):
204
+ """Draw the galactic plane the sphere.
205
+
206
+ Parameters
207
+ ----------
208
+ **kwargs
209
+ Keyword arguments passed to
210
+ `skyproj._Skyproj.draw_polygon`.
211
+ """
212
+ galactic_pole = SkyCoord(l=0 * u.degree, b=90 * u.degree, frame="galactic").icrs
213
+ self.draw_circle(galactic_pole.ra.deg, galactic_pole.dec.deg, **self.galactic_plane_kwargs)
214
+
215
+ def draw_zd(self, zd=90, **kwargs):
216
+ """Draw a circle at a given zenith distance.
217
+
218
+ Parameters
219
+ ----------
220
+ zd : `float`
221
+ The zenith distance to draw, in degrees.
222
+ Defaults to 90.
223
+ **kwargs
224
+ Keyword arguments passed to
225
+ `skyproj._Skyproj.draw_polygon`.
226
+
227
+ Notes
228
+ -----
229
+ This method relies on the site location and time (as an mjd) set in
230
+ the ``model_observatory`` element of the ``plot_dict``, which
231
+ should be of the class
232
+ `rubin_scheduler.scheduler.model_observatory.ModelObservatory`.
233
+ """
234
+ if "model_observatory" not in self.plot_dict or self.plot_dict["model_observatory"] is None:
235
+ warnings.warn("plot_dict['model_observatory'] must be set to plot a zenith distance circle")
236
+ return
237
+
238
+ model_observatory = self.plot_dict["model_observatory"]
239
+ lmst = model_observatory.return_conditions().lmst * 360 / 24
240
+ latitude = model_observatory.location.lat.deg
241
+ self.draw_circle(lmst, latitude, zd, **kwargs)
242
+
243
+ def draw_body(self, body="sun", **kwargs):
244
+ """Mark the sun or moon.
245
+
246
+ Parameters
247
+ ----------
248
+ body : `str`
249
+ The name of the body to draw, either `sun` or `moon`.
250
+ Defaults to `sun`
251
+ **kwargs
252
+ Keyword arguments passed to
253
+ `skyproj._Skyproj.scatter`
254
+
255
+ Notes
256
+ -----
257
+ This method relies on the site location and time (as an mjd) set in
258
+ the ``model_observatory`` element of the ``plot_dict``, which
259
+ should be of the class
260
+ `rubin_scheduler.scheduler.model_observatory.ModelObservatory`.
261
+ """
262
+ if "model_observatory" not in self.plot_dict or self.plot_dict["model_observatory"] is None:
263
+ warnings.warn(f"plot_dict['model_observatory'] must be set to plot the {body}")
264
+ return
265
+
266
+ mjd = self.plot_dict["model_observatory"].mjd
267
+ model_observatory = self.plot_dict["model_observatory"]
268
+ sun_moon_positions = model_observatory.almanac.get_sun_moon_positions(mjd)
269
+ ra = np.degrees(sun_moon_positions[f"{body}_RA"].item())
270
+ decl = np.degrees(sun_moon_positions[f"{body}_dec"].item())
271
+ self.skyproj.scatter(ra, decl, **kwargs)
272
+
273
+ def decorate(self):
274
+ """Add decorations/annotations to the sky plot.
275
+
276
+ Notes
277
+ -----
278
+ For decorations that depend on the time or location of the observer
279
+ (e.g., the horizon and sun and moon positions)
280
+ this method relies on the site location and time (as an mjd) set in
281
+ the ``model_observatory`` element of the ``plot_dict``, which
282
+ should be of the class
283
+ `rubin_scheduler.scheduler.model_observatory.ModelObservatory`.
284
+ Other decorations (e.g., the ecliptic and galactic plane) can
285
+ be shown even when ``model_observatory`` is not set.
286
+ """
287
+ decorations = self.plot_dict["decorations"]
288
+
289
+ if "ecliptic" in decorations:
290
+ self.draw_ecliptic()
291
+
292
+ if "galactic_plane" in decorations:
293
+ self.draw_galactic_plane()
294
+
295
+ if "sun" in decorations:
296
+ self.draw_body("sun", **self.sun_kwargs)
297
+
298
+ if "moon" in decorations:
299
+ self.draw_body("moon", **self.moon_kwargs)
300
+
301
+ if "horizon" in decorations:
302
+ self.draw_zd(**self.horizon_kwargs)
303
+
304
+ @abc.abstractmethod
305
+ def draw(self, metric_values, slicer):
306
+ raise NotImplementedError()
307
+
308
+ def __call__(self, metric_values, slicer, user_plot_dict, fig=None):
309
+ """Make a plot.
310
+
311
+ Parameters
312
+ ----------
313
+ metric_value : `numpy.ma.MaskedArray`
314
+ The metric values from the bundle.
315
+ slicer : `rubin_sim.maf.slicers.TwoDSlicer`
316
+ The slicer.
317
+ user_plot_dict: `dict`
318
+ Dictionary of plot parameters set by user
319
+ (overrides default values).
320
+ fig : `matplotlib.figure.Figure`
321
+ Matplotlib figure.
322
+ The default is ``None``, which starts new figure.
323
+
324
+ Returns
325
+ -------
326
+ fig : `matplotlib.figure.Figure`
327
+ Figure with the plot.
328
+ """
329
+ self._initialize_plot_dict(user_plot_dict)
330
+ self._prepare_skyproj(fig)
331
+ self.draw(metric_values, slicer)
332
+ self.decorate()
333
+
334
+ # Do not show axis labels unless they are set explicitly
335
+ # or specified as decorators.
336
+ if self.plot_dict["xlabel"] is None:
337
+ if "xlabel" not in self.plot_dict["decorations"]:
338
+ self.skyproj.ax.set_xlabel("", visible=False)
339
+ else:
340
+ self.skyproj.ax.set_xlabel(self.plot_dict["xlabel"])
341
+
342
+ if self.plot_dict["ylabel"] is None:
343
+ if "ylabel" not in self.plot_dict["decorations"]:
344
+ self.skyproj.ax.set_ylabel("", visible=False)
345
+ else:
346
+ self.skyproj.ax.set_ylabel(self.plot_dict["ylabel"])
347
+
348
+ if self.plot_dict["label"] is not None:
349
+ label_kwargs = {}
350
+ if "fontsize" in self.plot_dict:
351
+ label_kwargs["fontsize"] = self.plot_dict["fontsize"]
352
+ if "label_loc" in self.plot_dict:
353
+ label_kwargs["loc"] = self.plot_dict["label_loc"]
354
+ self.skyproj.ax.set_title(self.plot_dict["label"], **label_kwargs)
355
+
356
+ if self.plot_dict["title"] is not None:
357
+ title_kwargs = {}
358
+ if "fontsize" in self.plot_dict:
359
+ title_kwargs["fontsize"] = self.plot_dict["fontsize"]
360
+ self.figure.suptitle(self.plot_dict["title"], **title_kwargs)
361
+
362
+ return self.figure
363
+
364
+
365
+ class HpxmapPlotter(SkyprojPlotter):
366
+ default_hpixmap_kwargs = {"zoom": False}
367
+
368
+ def __init__(self):
369
+ super().__init__()
370
+ self.default_plot_dict["colorbar"] = True
371
+ self.object_plotter = False
372
+
373
+ def draw_colorbar(self):
374
+ """Add a color bar."""
375
+ plot_dict = self.plot_dict
376
+
377
+ colorbar_kwargs = {}
378
+ colorbar_kwargs.update(self.default_colorbar_kwargs)
379
+
380
+ if "extend" in self.plot_dict:
381
+ colorbar_kwargs["extendrect"] = self.plot_dict["extend"] == "neither"
382
+
383
+ if "cbar_format" in self.plot_dict:
384
+ colorbar_kwargs["format"] = self.plot_dict["cbar_format"]
385
+
386
+ if "cbar_orientation" in self.plot_dict:
387
+ colorbar_kwargs["orientation"] = self.plot_dict["cbar_orientation"]
388
+ match self.plot_dict["cbar_orientation"].lower():
389
+ case "vertical":
390
+ colorbar_kwargs["shrink"] = 0.5
391
+ colorbar_kwargs["location"] = "right"
392
+ case "horizontal":
393
+ colorbar_kwargs["location"] = "bottom"
394
+ case _:
395
+ orientation = self.plot_dict["cbar_orientation"]
396
+ raise NotImplementedError(f"cbar_orintation {orientation} is not supported")
397
+
398
+ colorbar = self.skyproj.draw_colorbar(**colorbar_kwargs)
399
+
400
+ colorbar.set_label(self.plot_dict["xlabel"], fontsize=self.plot_dict["fontsize"])
401
+
402
+ if "labelsize" in self.plot_dict and self.plot_dict["labelsize"] is not None:
403
+ colorbar.ax.tick_params(labelsize=plot_dict["labelsize"])
404
+
405
+ if "n_ticks" in self.plot_dict and self.plot_dict["n_ticks"] is not None:
406
+ tick_locator = mpl.ticker.MaxNLocator(nbins=plot_dict["n_ticks"])
407
+ colorbar.locator = tick_locator
408
+ colorbar.update_ticks()
409
+
410
+ # If outputing to PDF, this fixes the colorbar white stripes
411
+ if "cbar_edge" in self.plot_dict and self.plot_dict["cbar_edge"]:
412
+ colorbar.solids.set_edgecolor("face")
413
+
414
+ def decorate(self):
415
+ super().decorate()
416
+
417
+ if self.plot_dict["colorbar"]:
418
+ self.draw_colorbar()
419
+
420
+ def _transform_to_healpix(self, metric_value_in, slicer):
421
+ # Bin the values up on a healpix grid.
422
+ metric_value = _healbin(
423
+ slicer.slice_points["ra"],
424
+ slicer.slice_points["dec"],
425
+ metric_value_in.filled(slicer.badval),
426
+ nside=self.plot_dict["nside"],
427
+ reduce_func=self.plot_dict["reduce_func"],
428
+ fill_val=slicer.badval,
429
+ )
430
+ mask = np.zeros(metric_value.size)
431
+ mask[np.where(metric_value == slicer.badval)] = 1
432
+
433
+ metric_value = ma.array(metric_value, mask=mask)
434
+ return metric_value
435
+
436
+ def _compatible_color_limits(self, norm, clims):
437
+ # Log can't be 0
438
+ compatible = (norm != "log") or (clims[0] < 0 and clims[1] < 0) or (clims[0] > 0 and clims[1] > 0)
439
+ return compatible
440
+
441
+ def draw(self, metric_values_in, slicer):
442
+ """Draw the healpix map.
443
+
444
+ Parameters
445
+ ----------
446
+ metric_value : `numpy.ma.MaskedArray`
447
+ The metric values from the bundle.
448
+ slicer : `rubin_sim.maf.slicers.TwoDSlicer`
449
+ The slicer
450
+ """
451
+ kwargs = {}
452
+ kwargs.update(self.default_hpixmap_kwargs)
453
+
454
+ # Check if we have a valid HEALpix slicer
455
+ if "Heal" not in slicer.slicer_name:
456
+ hpix_map = self._transform_to_healpix(metric_values_in, slicer)
457
+ else:
458
+ hpix_map = metric_values_in.copy()
459
+
460
+ hpix_map = apply_zp_norm(hpix_map, self.plot_dict)
461
+
462
+ if "draw_hpxmap_kwargs" in self.plot_dict:
463
+ kwargs.update(self.plot_dict["draw_hpxmap_kwargs"])
464
+
465
+ try:
466
+ kwargs["cmap"] = set_color_map(self.plot_dict)
467
+ except AttributeError:
468
+ # Probably here because an invalid cmap was set
469
+ pass
470
+
471
+ if self.plot_dict["log_scale"]:
472
+ if "norm" in kwargs and kwargs["norm"] != "log":
473
+ raise ValueError("Contradictory values for color scale normalization set.")
474
+ kwargs["norm"] = "log"
475
+
476
+ clims = set_color_lims(hpix_map, self.plot_dict)
477
+ if "norm" not in kwargs or self._compatible_color_limits(kwargs["norm"], clims):
478
+ kwargs["vmin"] = clims[0]
479
+ kwargs["vmax"] = clims[1]
480
+ else:
481
+ warnings.warn(
482
+ "Using log normalization, but color limits pass through 0. "
483
+ "Adjusting so plotting doesn't fail"
484
+ )
485
+
486
+ # Filling in masked values must take place after automatic color limits
487
+ # might be calculated!
488
+
489
+ # This masking replicates the behavior of HealpixSkyMap, but is it
490
+ # what we really want to do? Why not use the default handling of
491
+ # masked values applied by skyproj?
492
+ if "mask_below" in self.plot_dict and self.plot_dict["mask_below"] is not None:
493
+ to_mask = np.where(hpix_map <= self.plot_dict["mask_below"])[0]
494
+ hpix_map.mask[to_mask] = True
495
+ hpix_map = hpix_map.filled(hp.UNSEEN)
496
+ else:
497
+ hpix_map = hpix_map.filled(slicer.badval)
498
+
499
+ self.skyproj.draw_hpxmap(hpix_map, **kwargs)
500
+
501
+
502
+ class VisitPerimeterPlotter(SkyprojPlotter):
503
+ default_visits_kwargs = {
504
+ "edgecolor": "black",
505
+ "linewidth": 0.2,
506
+ }
507
+
508
+ def __init__(self):
509
+ super().__init__()
510
+ self.plot_type = "SkyprojVisitPerimeter"
511
+ self.object_plotter = True
512
+
513
+ def draw(self, metric_values, slicer):
514
+ """Draw the perimeters of visits.
515
+
516
+ Parameters
517
+ ----------
518
+ metric_value : `numpy.ma.MaskedArray`
519
+ The metric values from the bundle.
520
+ slicer : `rubin_sim.maf.slicers.TwoDSlicer`
521
+ The slicer
522
+ """
523
+
524
+ # If there are no visits, just return
525
+ if metric_values is None or len(metric_values) == 0:
526
+ return
527
+
528
+ kwargs = {}
529
+ kwargs.update(self.default_visits_kwargs)
530
+
531
+ visits = metric_values[0]
532
+
533
+ if "draw_polygon_kwargs" in self.plot_dict:
534
+ kwargs.update(self.plot_dict["draw_polygon_kwargs"])
535
+
536
+ camera_perimeter_func = self.plot_dict["camera_perimeter_func"]
537
+
538
+ ras, decls = camera_perimeter_func(visits["fieldRA"], visits["fieldDec"], visits["rotSkyPos"])
539
+ for visit_ras, visit_decls in zip(ras, decls):
540
+ self.skyproj.draw_polygon(visit_ras, visit_decls, **kwargs)