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,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