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,1910 @@
1
+ __all__ = ("science_radar_batch",)
2
+
3
+ import astropy.units as u
4
+ import healpy as hp
5
+ import numpy as np
6
+
7
+ import rubin_sim.maf as maf
8
+ import rubin_sim.maf.maps as maps
9
+ import rubin_sim.maf.metric_bundles as mb
10
+ import rubin_sim.maf.metrics as metrics
11
+ import rubin_sim.maf.plots as plots
12
+ import rubin_sim.maf.slicers as slicers
13
+
14
+ from .common import extended_summary, filter_list, lightcurve_summary, standard_summary
15
+
16
+
17
+ def science_radar_batch(
18
+ runName="run name",
19
+ nside=64,
20
+ benchmarkArea=18000,
21
+ benchmarkNvisits=825,
22
+ minNvisits=750,
23
+ long_microlensing=True,
24
+ srd_only=False,
25
+ mjd0=None,
26
+ ):
27
+ """A batch of metrics for looking at survey performance relative to the
28
+ SRD and the main science drivers of LSST.
29
+
30
+ Parameters
31
+ ----------
32
+ runName : `str`, optional
33
+ The name of the opsim run.
34
+ nside : `int`, optional
35
+ The nside to use for the HealpixSlicer (where relevant).
36
+ benchmarkArea : `float`, optional
37
+ The benchmark value to use for fO_Area comparison.
38
+ benchmarkNvisits : `float`, optional
39
+ The benchmark value to use for fO_Nvisits comparisons.
40
+ minNvisits : `float`, optional
41
+ The value to use to establish the area covered by at least minNvis.
42
+ long_microlensing : `bool`, optional
43
+ Add the longer running microlensing metrics to the batch
44
+ (at a subset of crossing times only)
45
+ srd_only : `bool` , optional
46
+ Only return the SRD metrics
47
+ mjd0 : `float`, optional
48
+ Set the start time for the survey, for metrics which need
49
+ this information.
50
+
51
+ Returns
52
+ -------
53
+ metric_bundleDict : `dict` of `maf.MetricBundle`
54
+ """
55
+
56
+ bundleList = []
57
+ # Get some standard per-filter coloring and sql constraints
58
+ filterlist, colors, filterorders, filtersqls, filterinfo_label = filter_list(all=False)
59
+ (
60
+ allfilterlist,
61
+ allcolors,
62
+ allfilterorders,
63
+ allfiltersqls,
64
+ allfilterinfo_label,
65
+ ) = filter_list(all=True)
66
+
67
+ standardStats = standard_summary(with_count=False)
68
+
69
+ # This is the default slicer for most purposes in this batch.
70
+ # Note that the cache is on - if the metric requires a dust map,
71
+ # this is not the right slicer to use.
72
+ healpixslicer = slicers.HealpixSlicer(nside=nside, use_cache=True)
73
+ subsetPlots = [plots.HealpixSkyMap(), plots.HealpixHistogram()]
74
+
75
+ #########################
76
+ #########################
77
+ # SRD, DM, etc
78
+ #########################
79
+ #########################
80
+ # fO metric
81
+ displayDict = {"group": "SRD", "subgroup": "FO metrics", "order": 0}
82
+
83
+ # Configure the count metric which is what is used for f0 slicer.
84
+ metric = metrics.CountExplimMetric(metric_name="fO")
85
+ plotDict = {
86
+ "xlabel": "Number of Visits",
87
+ "asky": benchmarkArea,
88
+ "n_visits": minNvisits,
89
+ "x_min": 0,
90
+ "x_max": 1500,
91
+ }
92
+ summaryMetrics = [
93
+ metrics.FOArea(
94
+ nside=nside,
95
+ norm=False,
96
+ metric_name="fOArea",
97
+ asky=benchmarkArea,
98
+ n_visit=benchmarkNvisits,
99
+ ),
100
+ metrics.FOArea(
101
+ nside=nside,
102
+ norm=True,
103
+ metric_name="fOArea/benchmark",
104
+ asky=benchmarkArea,
105
+ n_visit=benchmarkNvisits,
106
+ ),
107
+ metrics.FONv(
108
+ nside=nside,
109
+ norm=False,
110
+ metric_name="fONv",
111
+ asky=benchmarkArea,
112
+ n_visit=benchmarkNvisits,
113
+ ),
114
+ metrics.FONv(
115
+ nside=nside,
116
+ norm=True,
117
+ metric_name="fONv/benchmark",
118
+ asky=benchmarkArea,
119
+ n_visit=benchmarkNvisits,
120
+ ),
121
+ metrics.FOArea(
122
+ nside=nside,
123
+ norm=False,
124
+ metric_name=f"fOArea_{minNvisits}",
125
+ asky=benchmarkArea,
126
+ n_visit=minNvisits,
127
+ ),
128
+ ]
129
+ caption = "The FO metric evaluates the overall efficiency of observing. "
130
+ caption += (
131
+ "foNv: out of %.2f sq degrees, the area receives at least X and a median of Y visits "
132
+ "(out of %d, if compared to benchmark). " % (benchmarkArea, benchmarkNvisits)
133
+ )
134
+ caption += (
135
+ "fOArea: this many sq deg (out of %.2f sq deg if compared "
136
+ "to benchmark) receives at least %d visits. " % (benchmarkArea, benchmarkNvisits)
137
+ )
138
+ displayDict["caption"] = caption
139
+ bundle = mb.MetricBundle(
140
+ metric,
141
+ healpixslicer,
142
+ "",
143
+ plot_dict=plotDict,
144
+ display_dict=displayDict,
145
+ summary_metrics=summaryMetrics,
146
+ plot_funcs=[plots.FOPlot()],
147
+ )
148
+ bundleList.append(bundle)
149
+
150
+ # Single visit depth distribution
151
+ displayDict["subgroup"] = "Visit Depths"
152
+ # Histogram values over all and per filter.
153
+
154
+ value = "fiveSigmaDepth"
155
+ for f in filterlist:
156
+ displayDict["caption"] = "Histogram of %s" % (value)
157
+ displayDict["caption"] += " for %s." % (filterinfo_label[f])
158
+ displayDict["order"] = filterorders[f]
159
+ m = metrics.CountMetric(value, metric_name="%s Histogram" % (value))
160
+ slicer = slicers.OneDSlicer(slice_col_name=value)
161
+ bundle = mb.MetricBundle(
162
+ m,
163
+ slicer,
164
+ filtersqls[f],
165
+ display_dict=displayDict,
166
+ )
167
+ bundleList.append(bundle)
168
+
169
+ displayDict["caption"] = ""
170
+ for f in filterlist:
171
+ slicer = maf.UniSlicer()
172
+ metric = maf.MedianMetric(col="fiveSigmaDepth")
173
+ bundle = mb.MetricBundle(
174
+ metric,
175
+ slicer,
176
+ filtersqls[f],
177
+ display_dict=displayDict,
178
+ )
179
+ bundleList.append(bundle)
180
+
181
+ ##############
182
+ # Astrometry
183
+ ###############
184
+
185
+ rmags_para = [22.4, 24.0]
186
+ rmags_pm = [20.5, 24.0]
187
+
188
+ # Set up parallax/dcr stackers.
189
+ parallaxStacker = maf.ParallaxFactorStacker()
190
+ dcrStacker = maf.DcrStacker()
191
+
192
+ # Set up parallax metrics.
193
+ displayDict["subgroup"] = "Parallax"
194
+ displayDict["order"] += 1
195
+ # Expected error on parallax at 10 AU.
196
+ plotmaxVals = (2.0, 15.0)
197
+ good_parallax_limit = 11.5
198
+ summary = [
199
+ metrics.AreaSummaryMetric(
200
+ area=18000,
201
+ reduce_func=np.median,
202
+ decreasing=False,
203
+ metric_name="Median Parallax Uncert (18k)",
204
+ ),
205
+ metrics.AreaThresholdMetric(
206
+ upper_threshold=good_parallax_limit,
207
+ metric_name="Area better than %.1f mas uncertainty" % good_parallax_limit,
208
+ ),
209
+ ]
210
+ summary.append(metrics.PercentileMetric(percentile=95, metric_name="95th Percentile Parallax Uncert"))
211
+ summary.extend(standard_summary())
212
+ for rmag, plotmax in zip(rmags_para, plotmaxVals):
213
+ plotDict = {"x_min": 0, "x_max": plotmax, "color_min": 0, "color_max": plotmax}
214
+ metric = metrics.ParallaxMetric(
215
+ metric_name="Parallax Uncert @ %.1f" % (rmag),
216
+ rmag=rmag,
217
+ normalize=False,
218
+ )
219
+ bundle = mb.MetricBundle(
220
+ metric,
221
+ healpixslicer,
222
+ "",
223
+ stacker_list=[parallaxStacker],
224
+ display_dict=displayDict,
225
+ plot_dict=plotDict,
226
+ summary_metrics=summary,
227
+ plot_funcs=subsetPlots,
228
+ )
229
+ bundleList.append(bundle)
230
+ displayDict["order"] += 1
231
+
232
+ # Parallax normalized to 'best possible'.
233
+ # This separates the effect of cadence from depth.
234
+ for rmag in rmags_para:
235
+ metric = metrics.ParallaxMetric(
236
+ metric_name="Normalized Parallax Uncert @ %.1f" % (rmag),
237
+ rmag=rmag,
238
+ normalize=True,
239
+ )
240
+ bundle = mb.MetricBundle(
241
+ metric,
242
+ healpixslicer,
243
+ "",
244
+ stacker_list=[parallaxStacker],
245
+ display_dict=displayDict,
246
+ summary_metrics=standard_summary(),
247
+ plot_funcs=subsetPlots,
248
+ )
249
+ bundleList.append(bundle)
250
+ displayDict["order"] += 1
251
+ # Parallax factor coverage.
252
+ for rmag in rmags_para:
253
+ metric = metrics.ParallaxCoverageMetric(metric_name="Parallax Coverage @ %.1f" % (rmag), rmag=rmag)
254
+ bundle = mb.MetricBundle(
255
+ metric,
256
+ healpixslicer,
257
+ "",
258
+ stacker_list=[parallaxStacker],
259
+ display_dict=displayDict,
260
+ summary_metrics=standard_summary(),
261
+ plot_funcs=subsetPlots,
262
+ )
263
+ bundleList.append(bundle)
264
+ displayDict["order"] += 1
265
+ # Parallax problems can be caused by HA and DCR degeneracies.
266
+ # Check their correlation.
267
+ for rmag in rmags_para:
268
+ metric = metrics.ParallaxDcrDegenMetric(
269
+ metric_name="Parallax-DCR degeneracy @ %.1f" % (rmag), rmag=rmag
270
+ )
271
+ caption = "Correlation between parallax offset magnitude and hour angle for a r=%.1f star." % (rmag)
272
+ caption += " (0 is good, near -1 or 1 is bad)."
273
+ bundle = mb.MetricBundle(
274
+ metric,
275
+ healpixslicer,
276
+ "",
277
+ stacker_list=[dcrStacker, parallaxStacker],
278
+ display_dict=displayDict,
279
+ summary_metrics=standard_summary(),
280
+ plot_funcs=subsetPlots,
281
+ )
282
+ bundleList.append(bundle)
283
+ displayDict["order"] += 1
284
+
285
+ # Proper Motion metrics.
286
+ displayDict["subgroup"] = "Proper Motion"
287
+ displayDict["order"] = 0
288
+ # Proper motion errors.
289
+ plotmaxVals = (1.0, 5.0)
290
+ summary = [
291
+ metrics.AreaSummaryMetric(
292
+ area=18000,
293
+ reduce_func=np.median,
294
+ decreasing=False,
295
+ metric_name="Median Proper Motion Uncert (18k)",
296
+ )
297
+ ]
298
+ summary.append(metrics.PercentileMetric(metric_name="95th Percentile Proper Motion Uncert"))
299
+ summary.extend(standard_summary())
300
+ for rmag, plotmax in zip(rmags_pm, plotmaxVals):
301
+ plotDict = {"x_min": 0, "x_max": plotmax, "color_min": 0, "color_max": plotmax}
302
+ metric = metrics.ProperMotionMetric(
303
+ metric_name="Proper Motion Uncert @ %.1f" % rmag,
304
+ rmag=rmag,
305
+ normalize=False,
306
+ )
307
+ bundle = mb.MetricBundle(
308
+ metric,
309
+ healpixslicer,
310
+ "",
311
+ display_dict=displayDict,
312
+ plot_dict=plotDict,
313
+ summary_metrics=summary,
314
+ plot_funcs=subsetPlots,
315
+ )
316
+ bundleList.append(bundle)
317
+ displayDict["order"] += 1
318
+ # Normalized proper motion.
319
+ for rmag in rmags_pm:
320
+ metric = metrics.ProperMotionMetric(
321
+ metric_name="Normalized Proper Motion Uncert @ %.1f" % rmag,
322
+ rmag=rmag,
323
+ normalize=True,
324
+ )
325
+ bundle = mb.MetricBundle(
326
+ metric,
327
+ healpixslicer,
328
+ "",
329
+ display_dict=displayDict,
330
+ summary_metrics=standard_summary(),
331
+ plot_funcs=subsetPlots,
332
+ )
333
+ bundleList.append(bundle)
334
+ displayDict["order"] += 1
335
+
336
+ # DCR precision metric
337
+ displayDict["subgroup"] = "DCR"
338
+ displayDict["order"] = 0
339
+ plotDict = {"caption": "Precision of DCR slope.", "percentile_clip": 95}
340
+ metric = metrics.DcrPrecisionMetric()
341
+ bundle = mb.MetricBundle(
342
+ metric,
343
+ healpixslicer,
344
+ "",
345
+ plot_dict=plotDict,
346
+ plot_funcs=subsetPlots,
347
+ display_dict=displayDict,
348
+ summary_metrics=standard_summary(with_count=False),
349
+ )
350
+ bundleList.append(bundle)
351
+
352
+ # Rapid Revisit
353
+ displayDict["subgroup"] = "Rapid Revisits"
354
+ displayDict["order"] = 0
355
+ # Calculate the actual number of revisits within 30 minutes.
356
+ dTmax = 30 # time in minutes
357
+ m2 = metrics.NRevisitsMetric(d_t=dTmax, normed=False, metric_name="NumberOfQuickRevisits")
358
+ plotDict = {"color_min": 400, "color_max": 2000, "x_min": 400, "x_max": 2000}
359
+ caption = "Number of consecutive visits with return times faster than %.1f minutes, " % (dTmax)
360
+ caption += "in any filter. "
361
+ displayDict["caption"] = caption
362
+ bundle = mb.MetricBundle(
363
+ m2,
364
+ healpixslicer,
365
+ "",
366
+ plot_dict=plotDict,
367
+ plot_funcs=subsetPlots,
368
+ display_dict=displayDict,
369
+ summary_metrics=standard_summary(with_count=False),
370
+ )
371
+ bundleList.append(bundle)
372
+ displayDict["order"] += 1
373
+
374
+ # Better version of the rapid revisit requirements:
375
+ # require a minimum number of visits between
376
+ # dtMin and dtMax, but also a minimum number of visits
377
+ # between dtMin and dtPair (the typical pair time).
378
+ # 1 means the healpix met the requirements (0 means did not).
379
+ dTmin = 40.0 / 60.0 # (minutes) 40s minimum for rapid revisit range
380
+ dTpairs = 20.0 # minutes (time when pairs should start kicking in)
381
+ dTmax = 30.0 # 30 minute maximum for rapid revisit range
382
+ nOne = 82 # Number of revisits between 40s-30m required
383
+ nTwo = 28 # Number of revisits between 40s - tPairs required.
384
+ pix_area = float(hp.nside2pixarea(nside, degrees=True))
385
+ scale = pix_area * hp.nside2npix(nside)
386
+ m1 = metrics.RapidRevisitMetric(
387
+ metric_name="RapidRevisits",
388
+ d_tmin=dTmin / 60.0 / 60.0 / 24.0,
389
+ d_tpairs=dTpairs / 60.0 / 24.0,
390
+ d_tmax=dTmax / 60.0 / 24.0,
391
+ min_n1=nOne,
392
+ min_n2=nTwo,
393
+ )
394
+ plotDict = {
395
+ "x_min": 0,
396
+ "x_max": 1,
397
+ "color_min": 0,
398
+ "color_max": 1,
399
+ "log_scale": False,
400
+ }
401
+ cutoff1 = 0.9
402
+ summaryStats = [metrics.FracAboveMetric(cutoff=cutoff1, scale=scale, metric_name="Area (sq deg)")]
403
+ caption = "Rapid Revisit: area that receives at least %d visits between %.3f and %.1f minutes, " % (
404
+ nOne,
405
+ dTmin,
406
+ dTmax,
407
+ )
408
+ caption += "with at least %d of those visits falling between %.3f and %.1f minutes. " % (
409
+ nTwo,
410
+ dTmin,
411
+ dTpairs,
412
+ )
413
+ caption += (
414
+ 'Summary statistic "Area" indicates the area on the sky which meets this requirement.'
415
+ " (SRD design specification is 2000 sq deg)."
416
+ )
417
+ displayDict["caption"] = caption
418
+ displayDict["order"] = 0
419
+ bundle = mb.MetricBundle(
420
+ m1,
421
+ healpixslicer,
422
+ "",
423
+ plot_dict=plotDict,
424
+ plot_funcs=subsetPlots,
425
+ display_dict=displayDict,
426
+ summary_metrics=summaryStats,
427
+ )
428
+ bundleList.append(bundle)
429
+
430
+ # For SRD batch only, return here.
431
+ if srd_only:
432
+ for b in bundleList:
433
+ b.set_run_name(runName)
434
+ bundleDict = mb.make_bundles_dict_from_list(bundleList)
435
+
436
+ return bundleDict
437
+
438
+ # Year Coverage
439
+ displayDict["subgroup"] = "Year Coverage"
440
+ metric = metrics.YearCoverageMetric()
441
+ for f in filterlist:
442
+ plotDict = {"color_min": 7, "color_max": 10, "color": colors[f]}
443
+ displayDict["caption"] = f"Number of years of coverage in {f} band."
444
+ displayDict["order"] = filterorders[f]
445
+ summary = [
446
+ metrics.AreaSummaryMetric(
447
+ area=18000,
448
+ reduce_func=np.mean,
449
+ decreasing=True,
450
+ metric_name="N Years (18k) %s" % f,
451
+ )
452
+ ]
453
+ bundle = mb.MetricBundle(
454
+ metric,
455
+ healpixslicer,
456
+ filtersqls[f],
457
+ plot_dict=plotDict,
458
+ info_label=filterinfo_label[f],
459
+ display_dict=displayDict,
460
+ summary_metrics=summary,
461
+ )
462
+ bundleList.append(bundle)
463
+
464
+ #########################
465
+ #########################
466
+ # Galaxies
467
+ #########################
468
+ #########################
469
+
470
+ # Run this per filter, to look at variations in counts
471
+ # of galaxies in blue bands?
472
+ displayDict = {
473
+ "group": "Galaxies",
474
+ "subgroup": "Galaxy Counts",
475
+ "order": 0,
476
+ "caption": None,
477
+ }
478
+ summary = [
479
+ metrics.AreaSummaryMetric(
480
+ area=18000,
481
+ reduce_func=np.sum,
482
+ decreasing=True,
483
+ metric_name="N Galaxies (18k)",
484
+ )
485
+ ]
486
+ summary.append(metrics.SumMetric(metric_name="N Galaxies (all)"))
487
+ # make sure slicer has cache off
488
+ slicer = slicers.HealpixSlicer(nside=nside, use_cache=False)
489
+ for f in filterlist:
490
+ plotDict = {"percentile_clip": 95.0, "n_ticks": 5, "color": colors[f]}
491
+ metric = maf.GalaxyCountsMetricExtended(filter_band=f, redshift_bin="all", nside=nside)
492
+ displayDict["caption"] = (
493
+ f"Number of galaxies across the sky, in {f} band. Generally, full survey footprint."
494
+ )
495
+ displayDict["order"] = filterorders[f]
496
+ bundle = mb.MetricBundle(
497
+ metric,
498
+ slicer,
499
+ filtersqls[f],
500
+ plot_dict=plotDict,
501
+ display_dict=displayDict,
502
+ summary_metrics=summary,
503
+ plot_funcs=subsetPlots,
504
+ )
505
+ bundleList.append(bundle)
506
+
507
+ displayDict["subgroup"] = "Surface Brightness"
508
+ summary = [metrics.MedianMetric()]
509
+ for filtername in "ugrizy":
510
+ displayDict["caption"] = "Surface brightness limit in %s, no extinction applied." % filtername
511
+ displayDict["order"] = filterorders[f]
512
+ sql = "filter='%s'" % filtername
513
+ metric = metrics.SurfaceBrightLimitMetric()
514
+ bundle = mb.MetricBundle(
515
+ metric,
516
+ healpixslicer,
517
+ sql,
518
+ display_dict=displayDict,
519
+ summary_metrics=summary,
520
+ plot_funcs=subsetPlots,
521
+ )
522
+ bundleList.append(bundle)
523
+
524
+ #########################
525
+ #########################
526
+ # Cosmology
527
+ #########################
528
+ #########################
529
+
530
+ bandpass = "i"
531
+ nfilters_needed = 6
532
+ lim_ebv = 0.2
533
+ offset = 0.1
534
+ mag_cuts = {
535
+ 1: 24.75 - offset,
536
+ 2: 25.12 - offset,
537
+ 3: 25.35 - offset,
538
+ 4: 25.5 - offset,
539
+ 5: 25.62 - offset,
540
+ 6: 25.72 - offset,
541
+ 7: 25.8 - offset,
542
+ 8: 25.87 - offset,
543
+ 9: 25.94 - offset,
544
+ 10: 26.0 - offset,
545
+ }
546
+ yrs = list(mag_cuts.keys())
547
+ maxYr = max(yrs)
548
+
549
+ displayDict = {"group": "Cosmology"}
550
+ subgroupCount = 1
551
+
552
+ displayDict["subgroup"] = f"{subgroupCount}: Static Science"
553
+ # Static Science
554
+ # Calculate the static science metrics - effective survey area,
555
+ # mean/median coadded depth, stdev of coadded depth and
556
+ # the 3x2ptFoM emulator.
557
+
558
+ dustmap = maps.DustMap(nside=nside, interp=False)
559
+ pix_area = hp.nside2pixarea(nside, degrees=True)
560
+ summaryMetrics = [
561
+ metrics.MeanMetric(),
562
+ metrics.MedianMetric(),
563
+ metrics.RmsMetric(),
564
+ metrics.CountRatioMetric(norm_val=1 / pix_area, metric_name="Effective Area (deg)"),
565
+ ]
566
+ displayDict["order"] = 0
567
+ slicer = slicers.HealpixSlicer(nside=nside, use_cache=False)
568
+ for yr_cut in yrs:
569
+ ptsrc_lim_mag_i_band = mag_cuts[yr_cut]
570
+ sqlconstraint = "night <= %s" % (yr_cut * 365.25 + 0.5)
571
+ sqlconstraint += " and scheduler_note not like 'DD%'"
572
+ info_label = f"{bandpass} band non-DD year {yr_cut}"
573
+ ThreebyTwoSummary = maf.StaticProbesFoMEmulatorMetric(nside=nside, metric_name="3x2ptFoM")
574
+
575
+ m = metrics.ExgalM5WithCuts(
576
+ lsst_filter=bandpass,
577
+ n_filters=nfilters_needed,
578
+ extinction_cut=lim_ebv,
579
+ depth_cut=ptsrc_lim_mag_i_band,
580
+ )
581
+ caption = (
582
+ f"Cosmology/Static science metrics are based on evaluating the region "
583
+ f"of the sky that meets the requirements (in year {yr_cut} of coverage"
584
+ f"in all {nfilters_needed} bands, a lower E(B-V) value than {lim_ebv} "
585
+ f"and at least a coadded depth of {ptsrc_lim_mag_i_band} in {bandpass}. "
586
+ f"From there the effective survey area, coadded depth, standard deviation of "
587
+ f"the depth, and a 3x2pt static science figure of merit emulator are "
588
+ f"calculated using the dust-extinction coadded depth map (over that reduced "
589
+ f"footprint)."
590
+ )
591
+ displayDict["caption"] = caption
592
+ bundle = mb.MetricBundle(
593
+ m,
594
+ slicer,
595
+ sqlconstraint,
596
+ maps_list=[dustmap],
597
+ info_label=info_label,
598
+ summary_metrics=summaryMetrics + [ThreebyTwoSummary],
599
+ # , ThreebyTwoSummary_simple],
600
+ display_dict=displayDict,
601
+ )
602
+ displayDict["order"] += 1
603
+ bundleList.append(bundle)
604
+
605
+ # LSS Science
606
+ # The only metric we have from LSS is the NGals metric -
607
+ # which is similar to the GalaxyCountsExtended
608
+ # metric, but evaluated only on the depth/dust cuts footprint.
609
+ subgroupCount += 1
610
+ displayDict["subgroup"] = f"{subgroupCount}: LSS"
611
+ displayDict["order"] = 0
612
+ plotDict = {"n_ticks": 5}
613
+ # Have to include all filters in query to check for filter coverage.
614
+ # Galaxy numbers calculated using 'bandpass' images only though.
615
+ sqlconstraint = "scheduler_note not like 'DD%'"
616
+ info_label = f"{bandpass} band galaxies non-DD"
617
+ metric = maf.DepthLimitedNumGalMetric(
618
+ nside=nside,
619
+ filter_band=bandpass,
620
+ redshift_bin="all",
621
+ nfilters_needed=nfilters_needed,
622
+ lim_mag_i_ptsrc=mag_cuts[maxYr],
623
+ lim_ebv=lim_ebv,
624
+ )
625
+ summary = [
626
+ metrics.AreaSummaryMetric(
627
+ area=18000,
628
+ reduce_func=np.sum,
629
+ decreasing=True,
630
+ metric_name="N Galaxies (18k)",
631
+ )
632
+ ]
633
+ summary.append(metrics.SumMetric(metric_name="N Galaxies (all)"))
634
+ slicer = slicers.HealpixSlicer(nside=nside, use_cache=False)
635
+ bundle = mb.MetricBundle(
636
+ metric,
637
+ slicer,
638
+ sqlconstraint,
639
+ plot_dict=plotDict,
640
+ info_label=info_label,
641
+ maps_list=[dustmap],
642
+ display_dict=displayDict,
643
+ summary_metrics=summary,
644
+ plot_funcs=subsetPlots,
645
+ )
646
+ bundleList.append(bundle)
647
+
648
+ # WL metrics
649
+ # Calculates the number of visits per pointing,
650
+ # after removing parts of the footprint due to dust/depth.
651
+ # Count visits in gri bands.
652
+ subgroupCount += 1
653
+ displayDict["subgroup"] = f"{subgroupCount}: WL"
654
+ displayDict["order"] = 0
655
+ sqlconstraint = "scheduler_note not like 'DD%' and (filter='g' or filter='r' or filter='i')"
656
+ info_label = "gri band non-DD"
657
+ minExpTime = 15
658
+ m = metrics.WeakLensingNvisits(
659
+ lsst_filter=bandpass,
660
+ depth_cut=mag_cuts[maxYr],
661
+ ebvlim=lim_ebv,
662
+ min_exp_time=minExpTime,
663
+ metric_name="WeakLensingNvisits",
664
+ )
665
+ slicer = slicers.HealpixSlicer(nside=nside, use_cache=False)
666
+ displayDict["caption"] = (
667
+ f"The number of visits per pointing, over a similarly reduced footprint as "
668
+ f"described above for the 3x2pt FOM, but allowing areas of sky with "
669
+ f"fewer than {nfilters_needed} filters. "
670
+ f"A cutoff of {minExpTime} removes very short visits."
671
+ )
672
+ bundle = mb.MetricBundle(
673
+ m,
674
+ slicer,
675
+ sqlconstraint,
676
+ maps_list=[dustmap],
677
+ info_label=info_label,
678
+ summary_metrics=standardStats,
679
+ display_dict=displayDict,
680
+ )
681
+ bundleList.append(bundle)
682
+
683
+ # Do the weak lensing per year
684
+ for year in np.arange(1, 10):
685
+ displayDict["order"] = year
686
+ sqlconstraint = (
687
+ "scheduler_note not like 'DD%'"
688
+ + " and (filter='g' or filter='r' or filter='i') and night < %i" % (year * 365.25)
689
+ )
690
+ m = metrics.WeakLensingNvisits(
691
+ lsst_filter=bandpass,
692
+ depth_cut=mag_cuts[year],
693
+ ebvlim=lim_ebv,
694
+ min_exp_time=minExpTime,
695
+ metric_name="WeakLensingNvisits_gri_year%i" % year,
696
+ )
697
+ bundle = mb.MetricBundle(
698
+ m,
699
+ slicer,
700
+ sqlconstraint,
701
+ maps_list=[dustmap],
702
+ info_label=info_label,
703
+ summary_metrics=standardStats,
704
+ display_dict=displayDict,
705
+ )
706
+ bundleList.append(bundle)
707
+
708
+ m = metrics.RIZDetectionCoaddExposureTime(
709
+ det_bands=["g", "r", "i"], metric_name="gri_exposure_time_year%i" % year
710
+ )
711
+ bundle = mb.MetricBundle(
712
+ m,
713
+ slicer,
714
+ sqlconstraint,
715
+ maps_list=[dustmap],
716
+ info_label=info_label,
717
+ summary_metrics=standardStats,
718
+ display_dict=displayDict,
719
+ )
720
+ bundleList.append(bundle)
721
+
722
+ sqlconstraint = (
723
+ "scheduler_note not like 'DD%'"
724
+ + " and (filter='r' or filter='i' or filter='z') and night < %i" % (year * 365.25)
725
+ )
726
+ m = metrics.WeakLensingNvisits(
727
+ lsst_filter=bandpass,
728
+ depth_cut=mag_cuts[year],
729
+ ebvlim=lim_ebv,
730
+ min_exp_time=minExpTime,
731
+ metric_name="WeakLensingNvisits_riz_year%i" % year,
732
+ )
733
+ bundle = mb.MetricBundle(
734
+ m,
735
+ slicer,
736
+ sqlconstraint,
737
+ maps_list=[dustmap],
738
+ info_label=info_label,
739
+ summary_metrics=standardStats,
740
+ display_dict=displayDict,
741
+ )
742
+ bundleList.append(bundle)
743
+
744
+ m = metrics.RIZDetectionCoaddExposureTime(
745
+ det_bands=["g", "r", "i"], metric_name="riz_exposure_time_year%i" % year
746
+ )
747
+ bundle = mb.MetricBundle(
748
+ m,
749
+ slicer,
750
+ sqlconstraint,
751
+ maps_list=[dustmap],
752
+ info_label=info_label,
753
+ summary_metrics=standardStats,
754
+ display_dict=displayDict,
755
+ )
756
+ bundleList.append(bundle)
757
+
758
+ subgroupCount += 1
759
+ displayDict["subgroup"] = f"{subgroupCount}: Camera Rotator"
760
+ metric1 = metrics.KuiperMetric("rotSkyPos")
761
+ metric2 = metrics.KuiperMetric("rotTelPos")
762
+ caption_root = "Kuiper statistic (0 is uniform, 1 is delta function) of the "
763
+ for f in filterlist:
764
+ for m in [metric1, metric2]:
765
+ plotDict = {"color": colors[f]}
766
+ displayDict["order"] = filterorders[f]
767
+ displayDict["caption"] = caption_root + f"{m.colname} for visits in {f} band."
768
+ bundleList.append(
769
+ mb.MetricBundle(
770
+ m,
771
+ healpixslicer,
772
+ filtersqls[f],
773
+ plot_dict=plotDict,
774
+ display_dict=displayDict,
775
+ summary_metrics=standardStats,
776
+ plot_funcs=subsetPlots,
777
+ )
778
+ )
779
+ # Kuiper per year in gri and riz
780
+ for year in np.arange(1, 10):
781
+ sqlconstraint = (
782
+ "scheduler_note not like 'DD%'"
783
+ + " and (filter='g' or filter='r' or filter='i') and night < %i" % (year * 365.25)
784
+ )
785
+ metric1 = metrics.KuiperMetric("rotSkyPos", metric_name="Kuiper_rotSkyPos_gri_year%i" % year)
786
+ metric2 = metrics.KuiperMetric("rotTelPos", metric_name="Kuiper_rotTelPos_gri_year%i" % year)
787
+ for metric in [metric1, metric2]:
788
+ bundleList.append(
789
+ mb.MetricBundle(
790
+ metric,
791
+ healpixslicer,
792
+ sqlconstraint,
793
+ plot_dict={},
794
+ display_dict=displayDict,
795
+ summary_metrics=standardStats,
796
+ plot_funcs=subsetPlots,
797
+ )
798
+ )
799
+
800
+ ##############
801
+ # SNe Ia
802
+ ##############
803
+ displayDict = {
804
+ "group": "Cosmology",
805
+ "subgroup": "5: SNe Ia",
806
+ "order": 0,
807
+ "caption": "Expected discoveries of SNeIa, using the SNNSNMetric.",
808
+ }
809
+ sne_nside = 16
810
+ sn_summary = [
811
+ metrics.MedianMetric(),
812
+ metrics.MeanMetric(),
813
+ metrics.SumMetric(metric_name="Total detected"),
814
+ metrics.CountMetric(metric_name="Total on sky", mask_val=0),
815
+ ]
816
+ snslicer = slicers.HealpixSlicer(nside=sne_nside, use_cache=False)
817
+ metric = metrics.SNNSNMetric(
818
+ n_bef=3,
819
+ n_aft=8,
820
+ coadd_night=True,
821
+ add_dust=False,
822
+ hard_dust_cut=0.25,
823
+ zmin=0.2,
824
+ zmax=0.5,
825
+ z_step=0.03,
826
+ daymax_step=3.0,
827
+ zlim_coeff=0.95,
828
+ gamma_name="gamma_WFD.hdf5",
829
+ verbose=False,
830
+ )
831
+ plotDict = {"percentile_clip": 95, "n_ticks": 5}
832
+ # Run without DDF observations
833
+ bundle = mb.MetricBundle(
834
+ metric,
835
+ snslicer,
836
+ "scheduler_note not like '%DD%'",
837
+ plot_dict=plotDict,
838
+ display_dict=displayDict,
839
+ info_label="DDF excluded",
840
+ summary_metrics=sn_summary,
841
+ plot_funcs=subsetPlots,
842
+ )
843
+
844
+ bundleList.append(bundle)
845
+
846
+ #########################
847
+ #########################
848
+ # AGN
849
+ #########################
850
+ #########################
851
+
852
+ # AGN structure function error
853
+ agnslicer = slicers.HealpixSlicer(nside=nside, use_cache=False)
854
+ dustmap = maps.DustMap(nside=nside)
855
+ displayDict = {"group": "AGN", "order": 0}
856
+
857
+ # Calculate the number of expected QSOs, in each band
858
+ for f in filterlist:
859
+ sql = filtersqls[f] + " and scheduler_note not like '%DD%'"
860
+ md = filterinfo_label[f] + " and non-DD"
861
+ summaryMetrics = [metrics.SumMetric(metric_name="Total QSO")]
862
+ zmin = 0.3
863
+ m = metrics.QSONumberCountsMetric(
864
+ f,
865
+ units="mag",
866
+ extinction_cut=1.0,
867
+ qlf_module="Shen20",
868
+ qlf_model="A",
869
+ sed_model="Richards06",
870
+ zmin=zmin,
871
+ zmax=None,
872
+ )
873
+ displayDict["subgroup"] = "nQSO"
874
+ displayDict["caption"] = (
875
+ "The expected number of QSOs in regions of low dust extinction,"
876
+ f"based on detection in {f} bandpass."
877
+ )
878
+ displayDict["order"] = filterorders[f]
879
+ bundleList.append(
880
+ mb.MetricBundle(
881
+ m,
882
+ agnslicer,
883
+ constraint=sql,
884
+ info_label=md,
885
+ run_name=runName,
886
+ maps_list=[dustmap],
887
+ summary_metrics=summaryMetrics,
888
+ display_dict=displayDict,
889
+ )
890
+ )
891
+
892
+ # Calculate the expected AGN structure function error
893
+ # These agn test magnitude values are determined by
894
+ # looking at the baseline median m5 depths
895
+ # For v1.7.1 these values are:
896
+ agn_m5 = {"u": 22.89, "g": 23.94, "r": 23.5, "i": 22.93, "z": 22.28, "y": 21.5}
897
+ # And the expected medians SF error at those values is about 0.04
898
+ summaryMetrics = extended_summary()
899
+ summaryMetrics += [metrics.AreaThresholdMetric(upper_threshold=0.03, metric_name="AreaThreshold_0.03")]
900
+ summaryMetrics += [metrics.AreaThresholdMetric(upper_threshold=0.06, metric_name="AreaThreshold_0.06")]
901
+ for f in filterlist:
902
+ m = metrics.SFUncertMetric(
903
+ mag=agn_m5[f],
904
+ bins=np.logspace(0, np.log10(3650), 16),
905
+ metric_name="AGN SF_uncert",
906
+ )
907
+ plotDict = {"color": colors[f], "color_min": 0, "color_max": 0.2}
908
+ displayDict["order"] = filterorders[f]
909
+ displayDict["subgroup"] = "SFUncert"
910
+ displayDict["caption"] = (
911
+ "Expected AGN structure function uncertainties, based on observations in "
912
+ f"{f} band, for an AGN of magnitude {agn_m5[f]:.2f}"
913
+ )
914
+ bundleList.append(
915
+ mb.MetricBundle(
916
+ m,
917
+ agnslicer,
918
+ constraint=filtersqls[f],
919
+ info_label=filterinfo_label[f],
920
+ run_name=runName,
921
+ maps_list=[dustmap],
922
+ plot_dict=plotDict,
923
+ summary_metrics=summaryMetrics,
924
+ display_dict=displayDict,
925
+ )
926
+ )
927
+
928
+ # Run the TimeLag for each filter *and* all filters
929
+ nquist_threshold = 2.2
930
+ lag = 100
931
+ summaryMetrics = extended_summary()
932
+ summaryMetrics += [metrics.AreaThresholdMetric(lower_threshold=nquist_threshold)]
933
+ m = metrics.AgnTimeLagMetric(threshold=nquist_threshold, lag=lag)
934
+ for f in allfilterlist:
935
+ plotDict = {
936
+ "color": allcolors[f],
937
+ "color_min": 0,
938
+ "color_max": 5,
939
+ "percentile_clip": 95,
940
+ }
941
+ displayDict["order"] = allfilterorders[f]
942
+ displayDict["subgroup"] = "Time Lags"
943
+ displayDict["caption"] = (
944
+ f"Comparion of the time between visits compared to a defined sampling gap ({lag} days) in "
945
+ f"{f} band."
946
+ )
947
+ bundleList.append(
948
+ mb.MetricBundle(
949
+ m,
950
+ agnslicer,
951
+ constraint=allfiltersqls[f],
952
+ info_label=allfilterinfo_label[f],
953
+ run_name=runName,
954
+ maps_list=[dustmap],
955
+ plot_dict=plotDict,
956
+ summary_metrics=summaryMetrics,
957
+ display_dict=displayDict,
958
+ )
959
+ )
960
+
961
+ # Run the TimeLag for each filter *and* all filters but for 5 days
962
+ nquist_threshold = 2.2
963
+ lag = 5
964
+ summaryMetrics = extended_summary()
965
+ summaryMetrics += [metrics.AreaThresholdMetric(lower_threshold=nquist_threshold)]
966
+ m = metrics.AgnTimeLagMetric(threshold=nquist_threshold, lag=lag)
967
+ for f in allfilterlist:
968
+ plotDict = {
969
+ "color": allcolors[f],
970
+ "color_min": 0,
971
+ "color_max": 5,
972
+ "percentile_clip": 95,
973
+ }
974
+ displayDict["order"] = allfilterorders[f]
975
+ displayDict["subgroup"] = "Time Lags"
976
+ displayDict["caption"] = (
977
+ f"Comparion of the time between visits compared to a defined sampling gap ({lag} days) in "
978
+ f"{f} band."
979
+ )
980
+ bundleList.append(
981
+ mb.MetricBundle(
982
+ m,
983
+ agnslicer,
984
+ constraint=allfiltersqls[f],
985
+ info_label=allfilterinfo_label[f],
986
+ run_name=runName,
987
+ maps_list=[dustmap],
988
+ plot_dict=plotDict,
989
+ summary_metrics=summaryMetrics,
990
+ display_dict=displayDict,
991
+ )
992
+ )
993
+
994
+ #########################
995
+ #########################
996
+ # Strong Lensing
997
+ #########################
998
+ #########################
999
+
1000
+ # TDC metric
1001
+ # Calculate a subset of DESC WFD-related metrics.
1002
+ if nside > 64:
1003
+ nside_tdc = 64
1004
+ else:
1005
+ nside_tdc = nside
1006
+ displayDict = {"group": "Strong Lensing"}
1007
+ displayDict["subgroup"] = "Lens Time Delay"
1008
+
1009
+ tdc_plots = [plots.HealpixSkyMap(), plots.HealpixHistogram()]
1010
+ plotDict = {"x_min": 0.01, "color_min": 0.01, "percentile_clip": 70, "n_ticks": 5}
1011
+ tdc_summary = [metrics.MeanMetric(), metrics.MedianMetric(), metrics.RmsMetric()]
1012
+ # Ideally need a way to do better on calculating the summary metrics
1013
+ # for the high accuracy area.
1014
+ slicer = slicers.HealpixSlicer(nside=nside_tdc, use_cache=False)
1015
+ tdcMetric = metrics.TdcMetric(metric_name="TDC")
1016
+ dustmap = maps.DustMap(nside=nside_tdc, interp=False)
1017
+ bundle = mb.MetricBundle(
1018
+ tdcMetric,
1019
+ slicer,
1020
+ constraint="",
1021
+ display_dict=displayDict,
1022
+ plot_dict=plotDict,
1023
+ plot_funcs=tdc_plots,
1024
+ maps_list=[dustmap],
1025
+ summary_metrics=tdc_summary,
1026
+ )
1027
+ bundleList.append(bundle)
1028
+
1029
+ # Strongly lensed SNe
1030
+ displayDict["group"] = "Strong Lensing"
1031
+ displayDict["subgroup"] = "SLSN"
1032
+ displayDict["caption"] = "Strongly Lensed SNe, evaluated with the addition of galactic dust extinction."
1033
+ metric = metrics.SNSLMetric()
1034
+ slicer = slicers.HealpixSlicer(nside=nside_tdc, use_cache=False)
1035
+ plotDict = {}
1036
+ bundle = mb.MetricBundle(
1037
+ metric,
1038
+ slicer,
1039
+ "",
1040
+ run_name=runName,
1041
+ plot_dict=plotDict,
1042
+ summary_metrics=metrics.SumMetric(metric_name="Total detected"),
1043
+ display_dict=displayDict,
1044
+ )
1045
+ bundleList.append(bundle)
1046
+
1047
+ #########################
1048
+ #########################
1049
+ # Variables and Transients
1050
+ #########################
1051
+ #########################
1052
+
1053
+ # Periodic Stars
1054
+ displayDict = {"group": "Variables/Transients", "order": 0}
1055
+
1056
+ # PeriodicStarModulation metric
1057
+ # colors for c type RRLyrae
1058
+ displayDict["subgroup"] = "Periodic Star Modulation"
1059
+ I_rrc_lmc = 18.9
1060
+ V_rrc_lmc = 19.2
1061
+ Vi = V_rrc_lmc - (2.742 * 0.08) - 18.5
1062
+ Ii = I_rrc_lmc - (1.505 * 0.08) - 18.5
1063
+ ii_rrc = Ii + 0.386 * 0.013 + 0.397 # 0.013 = (i-z)_0
1064
+ gi_rrc = ii_rrc + 1.481 * (Vi - Ii) - 0.536
1065
+ ri_rrc = (1 / 0.565) * (Vi - 0.435 * gi_rrc + 0.016)
1066
+ ui_rrc = gi_rrc + 0.575
1067
+ zi_rrc = ii_rrc - 0.013
1068
+ yi_rrc = zi_rrc
1069
+ rrc = np.array([ui_rrc, gi_rrc, ri_rrc, ii_rrc, zi_rrc, yi_rrc])
1070
+ time_intervals = (15, 30)
1071
+ distMod = (18, 19, 20, 21)
1072
+ summaryStats = [metrics.MeanMetric(), metrics.MedianMetric(), metrics.MaxMetric()]
1073
+ slicer = slicers.HealpixSlicer(nside=8)
1074
+ for time_interval in time_intervals:
1075
+ for dM in distMod:
1076
+ displayDict["caption"] = (
1077
+ "Periodic star modulation metric, evaluates the likelihood of "
1078
+ "measuring variation in an RRLyrae periodic variable. "
1079
+ "Evaluated based on the full LSST survey data. "
1080
+ f"Searching time interval of {time_interval} and distance modulus {dM}."
1081
+ )
1082
+ displayDict["order"] += 1
1083
+ m = maf.PeriodicStarModulationMetric(
1084
+ period=0.3,
1085
+ amplitude=0.3,
1086
+ random_phase=True,
1087
+ time_interval=time_interval,
1088
+ n_monte=100,
1089
+ period_tol=0.002,
1090
+ amp_tol=0.01,
1091
+ means=rrc + dM,
1092
+ mag_tol=0.01,
1093
+ n_bands=3,
1094
+ )
1095
+ # Run this on year 1-2.
1096
+ bundle = mb.MetricBundle(
1097
+ m,
1098
+ slicer,
1099
+ "night < 365.25*2",
1100
+ display_dict=displayDict,
1101
+ run_name=runName,
1102
+ summary_metrics=summaryStats,
1103
+ info_label=f"dm {dM} interval {time_interval} RRc Year 1-2",
1104
+ )
1105
+ bundleList.append(bundle)
1106
+
1107
+ # PulsatingStarRecovery metric (to be added; Marcella)
1108
+
1109
+ # our periodic star metrics
1110
+ displayDict["subgroup"] = "Periodic Stars"
1111
+ displayDict["order"] = 0
1112
+ for period in [0.5, 1, 2]:
1113
+ for magnitude in [21.0, 24.0]:
1114
+ amplitudes = [0.05, 0.1, 1.0]
1115
+ periods = [period] * len(amplitudes)
1116
+ starMags = [magnitude] * len(amplitudes)
1117
+
1118
+ plotDict = {
1119
+ "n_ticks": 3,
1120
+ "color_min": 0,
1121
+ "color_max": 3,
1122
+ "x_min": 0,
1123
+ "x_max": 3,
1124
+ }
1125
+ info_label = "P_%.1f_Mag_%.0f_Amp_0.05-0.1-1" % (period, magnitude)
1126
+ sql = ""
1127
+ displayDict["caption"] = (
1128
+ "Metric evaluates if a periodic signal of period %.1f days could "
1129
+ "be detected for an r=%i star. A variety of amplitudes of periodicity "
1130
+ "are tested: [1, 0.1, and 0.05] mag amplitudes, which correspond to "
1131
+ "metric values of [1, 2, or 3]. " % (period, magnitude)
1132
+ )
1133
+ metric = metrics.PeriodicDetectMetric(
1134
+ periods=periods,
1135
+ star_mags=starMags,
1136
+ amplitudes=amplitudes,
1137
+ metric_name="PeriodicDetect",
1138
+ )
1139
+ bundle = mb.MetricBundle(
1140
+ metric,
1141
+ healpixslicer,
1142
+ sql,
1143
+ info_label=info_label,
1144
+ display_dict=displayDict,
1145
+ plot_dict=plotDict,
1146
+ plot_funcs=subsetPlots,
1147
+ summary_metrics=standardStats,
1148
+ )
1149
+ bundleList.append(bundle)
1150
+ displayDict["order"] += 1
1151
+
1152
+ # our periodic star metrics - first two years only
1153
+ displayDict["order"] = 1
1154
+ for period in [0.5, 1, 2]:
1155
+ for magnitude in [21.0, 24.0]:
1156
+ amplitudes = [0.05, 0.1, 1.0]
1157
+ periods = [period] * len(amplitudes)
1158
+ starMags = [magnitude] * len(amplitudes)
1159
+
1160
+ plotDict = {
1161
+ "n_ticks": 3,
1162
+ "color_min": 0,
1163
+ "color_max": 3,
1164
+ "x_min": 0,
1165
+ "x_max": 3,
1166
+ }
1167
+ info_label = "P_%.1f_Mag_%.0f_Amp_0.05-0.1-1 Yr 2" % (period, magnitude)
1168
+ sql = "night < 365.5*2"
1169
+ displayDict["caption"] = (
1170
+ "Metric evaluates if a periodic signal of period %.1f days could "
1171
+ "be detected for an r=%i star, within the first two years. "
1172
+ "A variety of amplitudes of periodicity "
1173
+ "are tested: [1, 0.1, and 0.05] mag amplitudes, which correspond to "
1174
+ "metric values of [1, 2, or 3]. " % (period, magnitude)
1175
+ )
1176
+ metric = metrics.PeriodicDetectMetric(
1177
+ periods=periods,
1178
+ star_mags=starMags,
1179
+ amplitudes=amplitudes,
1180
+ metric_name="PeriodicDetect",
1181
+ )
1182
+ bundle = mb.MetricBundle(
1183
+ metric,
1184
+ healpixslicer,
1185
+ sql,
1186
+ info_label=info_label,
1187
+ display_dict=displayDict,
1188
+ plot_dict=plotDict,
1189
+ plot_funcs=subsetPlots,
1190
+ summary_metrics=standardStats,
1191
+ )
1192
+ bundleList.append(bundle)
1193
+ displayDict["order"] += 1
1194
+
1195
+ # Tidal Disruption Events
1196
+ displayDict["subgroup"] = "TDE"
1197
+ displayDict["caption"] = "TDE lightcurves that could be identified"
1198
+ displayDict["order"] = 0
1199
+ metric = maf.TdePopMetric(mjd0=mjd0)
1200
+ tdeslicer = maf.generate_tde_pop_slicer()
1201
+ bundle = mb.MetricBundle(
1202
+ metric,
1203
+ tdeslicer,
1204
+ "",
1205
+ run_name=runName,
1206
+ summary_metrics=lightcurve_summary(),
1207
+ display_dict=displayDict,
1208
+ plot_funcs=[plots.HealpixSkyMap()],
1209
+ )
1210
+ bundleList.append(bundle)
1211
+
1212
+ displayDict["caption"] = "TDE lightcurves quality"
1213
+ metric = maf.TdePopMetricQuality(metric_name="TDE_Quality")
1214
+ bundle = mb.MetricBundle(
1215
+ metric,
1216
+ tdeslicer,
1217
+ "",
1218
+ run_name=runName,
1219
+ summary_metrics=lightcurve_summary(),
1220
+ display_dict=displayDict,
1221
+ plot_funcs=[plots.HealpixSkyMap()],
1222
+ )
1223
+ bundleList.append(bundle)
1224
+
1225
+ # Microlensing events
1226
+
1227
+ displayDict["subgroup"] = "Microlensing"
1228
+ plotDict = {"nside": 128}
1229
+
1230
+ n_events = 10000
1231
+ # Let's evaluate a variety of crossing times
1232
+ crossing_times = [
1233
+ [1, 5],
1234
+ [5, 10],
1235
+ [10, 20],
1236
+ [20, 30],
1237
+ [30, 60],
1238
+ [60, 90],
1239
+ [100, 200],
1240
+ [200, 500],
1241
+ [500, 1000],
1242
+ ]
1243
+ metric = maf.MicrolensingMetric()
1244
+ summaryMetrics = maf.batches.lightcurve_summary()
1245
+ order = 0
1246
+ for crossing in crossing_times:
1247
+ displayDict["caption"] = "Microlensing events with crossing times between %i to %i days." % (
1248
+ crossing[0],
1249
+ crossing[1],
1250
+ )
1251
+ displayDict["order"] = order
1252
+ order += 1
1253
+ slicer = maf.generate_microlensing_slicer(
1254
+ min_crossing_time=crossing[0],
1255
+ max_crossing_time=crossing[1],
1256
+ n_events=n_events,
1257
+ )
1258
+ bundleList.append(
1259
+ maf.MetricBundle(
1260
+ metric,
1261
+ slicer,
1262
+ None,
1263
+ run_name=runName,
1264
+ summary_metrics=summaryMetrics,
1265
+ info_label=f"tE {crossing[0]}_{crossing[1]} days",
1266
+ display_dict=displayDict,
1267
+ plot_dict=plotDict,
1268
+ plot_funcs=[plots.HealpixSkyMap()],
1269
+ )
1270
+ )
1271
+
1272
+ if long_microlensing:
1273
+ n_events = 10000
1274
+ # Let's evaluate a subset of the crossing times for these
1275
+ crossing_times = [
1276
+ [10, 20],
1277
+ [20, 30],
1278
+ [30, 60],
1279
+ [200, 500],
1280
+ ]
1281
+ metric_Npts = maf.MicrolensingMetric(metric_calc="Npts")
1282
+ summaryMetrics = maf.batches.microlensing_summary(metric_type="Npts")
1283
+ order = 0
1284
+ for crossing in crossing_times:
1285
+ slicer = maf.generate_microlensing_slicer(
1286
+ min_crossing_time=crossing[0],
1287
+ max_crossing_time=crossing[1],
1288
+ n_events=n_events,
1289
+ )
1290
+ displayDict["caption"] = "Microlensing events with crossing times between %i to %i days." % (
1291
+ crossing[0],
1292
+ crossing[1],
1293
+ )
1294
+ displayDict["order"] = order
1295
+ order += 1
1296
+ bundleList.append(
1297
+ maf.MetricBundle(
1298
+ metric_Npts,
1299
+ slicer,
1300
+ None,
1301
+ run_name=runName,
1302
+ summary_metrics=summaryMetrics,
1303
+ info_label=f"tE {crossing[0]}_{crossing[1]} days",
1304
+ display_dict=displayDict,
1305
+ plot_dict=plotDict,
1306
+ plot_funcs=[],
1307
+ )
1308
+ )
1309
+
1310
+ metric_Fisher = maf.MicrolensingMetric(metric_calc="Fisher")
1311
+ summaryMetrics = maf.batches.microlensing_summary(metric_type="Fisher")
1312
+ order = 0
1313
+ for crossing in crossing_times:
1314
+ displayDict["caption"] = "Microlensing events with crossing times between %i to %i days." % (
1315
+ crossing[0],
1316
+ crossing[1],
1317
+ )
1318
+ displayDict["order"] = order
1319
+ order += 1
1320
+ slicer = maf.generate_microlensing_slicer(
1321
+ min_crossing_time=crossing[0],
1322
+ max_crossing_time=crossing[1],
1323
+ n_events=n_events,
1324
+ )
1325
+ bundleList.append(
1326
+ maf.MetricBundle(
1327
+ metric_Fisher,
1328
+ slicer,
1329
+ None,
1330
+ run_name=runName,
1331
+ summary_metrics=summaryMetrics,
1332
+ info_label=f"tE {crossing[0]}_{crossing[1]} days",
1333
+ display_dict=displayDict,
1334
+ plot_dict=plotDict,
1335
+ plot_funcs=[],
1336
+ )
1337
+ )
1338
+
1339
+ # Kilonovae metric
1340
+ displayDict["group"] = "Variables/Transients"
1341
+ displayDict["subgroup"] = "KNe"
1342
+ n_events = 500000
1343
+ caption = f"KNe metric, injecting {n_events} lightcurves over the entire sky, GW170817-like only."
1344
+ caption += " Ignoring DDF observations."
1345
+ displayDict["caption"] = caption
1346
+ displayDict["order"] = 0
1347
+ # Kilonova parameters
1348
+ inj_params_list = [
1349
+ {"mej_dyn": 0.005, "mej_wind": 0.050, "phi": 30, "theta": 25.8},
1350
+ ]
1351
+ filename = maf.get_kne_filename(inj_params_list)
1352
+ kneslicer = maf.generate_kn_pop_slicer(n_events=n_events, n_files=len(filename), d_min=10, d_max=600)
1353
+ metric = maf.KNePopMetric(
1354
+ output_lc=False,
1355
+ file_list=filename,
1356
+ metric_name="KNePopMetric_single",
1357
+ mjd0=mjd0,
1358
+ )
1359
+ bundle = mb.MetricBundle(
1360
+ metric,
1361
+ kneslicer,
1362
+ "scheduler_note not like 'DD%'",
1363
+ run_name=runName,
1364
+ info_label="single model",
1365
+ summary_metrics=lightcurve_summary(),
1366
+ display_dict=displayDict,
1367
+ plot_funcs=[plots.HealpixSkyMap()],
1368
+ )
1369
+ bundleList.append(bundle)
1370
+
1371
+ n_events = 500000
1372
+ caption = f"KNe metric, injecting {n_events} lightcurves over the entire sky, entire model population."
1373
+ caption += " Ignoring DDF observations."
1374
+ displayDict["caption"] = caption
1375
+ displayDict["order"] = 1
1376
+ # Kilonova parameters
1377
+ filename = maf.get_kne_filename(None)
1378
+ kneslicer_allkne = maf.generate_kn_pop_slicer(
1379
+ n_events=n_events, n_files=len(filename), d_min=10, d_max=600
1380
+ )
1381
+ metric_allkne = maf.KNePopMetric(output_lc=False, file_list=filename, metric_name="KNePopMetric_all")
1382
+ bundle = mb.MetricBundle(
1383
+ metric_allkne,
1384
+ kneslicer_allkne,
1385
+ "scheduler_note not like 'DD%'",
1386
+ run_name=runName,
1387
+ info_label="all models",
1388
+ summary_metrics=lightcurve_summary(),
1389
+ display_dict=displayDict,
1390
+ plot_funcs=[plots.HealpixSkyMap()],
1391
+ )
1392
+ bundleList.append(bundle)
1393
+
1394
+ # General time intervals
1395
+ displayDict = {
1396
+ "group": "TimeGaps",
1397
+ "subgroup": "Time",
1398
+ "caption": None,
1399
+ "order": 0,
1400
+ }
1401
+
1402
+ # Logarithmically spaced gaps from 30s to 5 years
1403
+ tMin = 30 / 60 / 60 / 24.0 # 30s
1404
+ tMax = 5 * 365.25 # 5 years
1405
+ tgaps = np.logspace(np.log10(tMin), np.log10(tMax), 100)
1406
+
1407
+ for f in filterlist:
1408
+ m1 = metrics.TgapsMetric(bins=tgaps, all_gaps=False)
1409
+ plotDict = {
1410
+ "bins": tgaps,
1411
+ "xscale": "log",
1412
+ "y_min": 0,
1413
+ "figsize": (8, 6),
1414
+ "ylabel": "Number of observation pairs",
1415
+ "xlabel": "Time gap between pairs of visits (days)",
1416
+ "color": colors[f],
1417
+ }
1418
+ plotFuncs = [plots.SummaryHistogram()]
1419
+ displayDict["caption"] = (
1420
+ f"Summed Histogram of time between visits at each point in the sky, " f"in {f} band(s)."
1421
+ )
1422
+ displayDict["order"] = filterorders[f]
1423
+ bundleList.append(
1424
+ mb.MetricBundle(
1425
+ m1,
1426
+ healpixslicer,
1427
+ constraint=filtersqls[f],
1428
+ info_label=filterinfo_label[f],
1429
+ run_name=runName,
1430
+ plot_dict=plotDict,
1431
+ plot_funcs=plotFuncs,
1432
+ display_dict=displayDict,
1433
+ )
1434
+ )
1435
+
1436
+ gaps = [3.0, 7.0, 24.0]
1437
+ for gap in gaps:
1438
+ summary_stats = []
1439
+ summary_stats.append(
1440
+ metrics.AreaSummaryMetric(
1441
+ area=18000,
1442
+ reduce_func=np.median,
1443
+ decreasing=True,
1444
+ metric_name="Median N gaps in %s at %ihr in top 18k" % (f, gap),
1445
+ )
1446
+ )
1447
+
1448
+ summary_stats.append(
1449
+ metrics.AreaSummaryMetric(
1450
+ area=18000,
1451
+ reduce_func=np.mean,
1452
+ decreasing=True,
1453
+ metric_name="Mean N gaps in %s at %ihr in top 18k" % (f, gap),
1454
+ )
1455
+ )
1456
+
1457
+ summary_stats.append(metrics.MeanMetric())
1458
+ summary_stats.append(metrics.MedianMetric())
1459
+
1460
+ m2 = metrics.GapsMetric(
1461
+ time_scale=gap,
1462
+ metric_name="Gaps_%ihr" % gap,
1463
+ )
1464
+ plotFuncs = [plots.HealpixSkyMap(), plots.HealpixHistogram()]
1465
+ plotDict = {"color_min": 0, "color": colors[f], "percentile_clip": 95}
1466
+ displayDict["caption"] = (
1467
+ "Number of times the timescale of ~%i hours is sampled in %s band(s)." % (gap, f)
1468
+ )
1469
+ displayDict["order"] = filterorders[f]
1470
+ bundleList.append(
1471
+ mb.MetricBundle(
1472
+ m2,
1473
+ healpixslicer,
1474
+ constraint=filtersqls[f],
1475
+ info_label=filterinfo_label[f],
1476
+ run_name=runName,
1477
+ summary_metrics=summary_stats,
1478
+ plot_dict=plotDict,
1479
+ plot_funcs=plotFuncs,
1480
+ display_dict=displayDict,
1481
+ )
1482
+ )
1483
+
1484
+ # FilterPairTgaps Metric (for TVS)
1485
+ m1 = maf.FilterPairTGapsMetric()
1486
+ plotDict = {"color_min": 0, "color_max": 1500, "x_min": 0, "x_max": 2000}
1487
+ displayDict["order"] = 0
1488
+ displayDict["caption"] = (
1489
+ "Evaluate the distribution of filter pairs and time gaps at each point in "
1490
+ "the sky. The time gaps are evaluated on a logarithmic spacing "
1491
+ "from 0-100 days for pairs of filters, and 0-3650 days for same filters."
1492
+ )
1493
+ summarystats = [
1494
+ metrics.MedianMetric(),
1495
+ metrics.MeanMetric(),
1496
+ metrics.PercentileMetric(percentile=80),
1497
+ ]
1498
+ bundle = maf.MetricBundle(
1499
+ m1,
1500
+ healpixslicer,
1501
+ None,
1502
+ run_name=runName,
1503
+ summary_metrics=summarystats,
1504
+ plot_dict=plotDict,
1505
+ display_dict=displayDict,
1506
+ )
1507
+ bundleList.append(bundle)
1508
+
1509
+ # Presto KNe metric
1510
+ displayDict["group"] = "Variables/Transients"
1511
+ displayDict["subgroup"] = "Presto KNe"
1512
+ displayDict["caption"] = "Probability of detecting and classifying a KNe"
1513
+ prestoslicer = maf.generate_presto_pop_slicer(skyregion="extragalactic")
1514
+ metric = maf.PrestoColorKNePopMetric(
1515
+ skyregion="extragalactic",
1516
+ metric_name="PrestoKNe",
1517
+ mjd0=mjd0,
1518
+ )
1519
+ summaryMetrics_kne = [maf.MedianMetric(), maf.SumMetric()]
1520
+ bundleList.append(
1521
+ maf.MetricBundle(
1522
+ metric,
1523
+ prestoslicer,
1524
+ None,
1525
+ run_name=runName,
1526
+ display_dict=displayDict,
1527
+ summary_metrics=summaryMetrics_kne,
1528
+ )
1529
+ )
1530
+
1531
+ # color plus slope metrics
1532
+ displayDict["group"] = "Variables/Transients"
1533
+ displayDict["subgroup"] = "Color and slope"
1534
+ displayDict["caption"] = "Number of times a color and slope are measured in a night"
1535
+ sql = "visitExposureTime > 19"
1536
+ metric = maf.ColorSlopeMetric()
1537
+ summaryMetrics_cs = [maf.SumMetric()]
1538
+ bundleList.append(
1539
+ maf.MetricBundle(
1540
+ metric,
1541
+ healpixslicer,
1542
+ sql,
1543
+ run_name=runName,
1544
+ display_dict=displayDict,
1545
+ summary_metrics=summaryMetrics_cs,
1546
+ )
1547
+ )
1548
+
1549
+ displayDict["group"] = "Variables/Transients"
1550
+ displayDict["subgroup"] = "Color and slope"
1551
+ displayDict["caption"] = "Number of times a color and slope are measured over 2 nights."
1552
+ sql = "visitExposureTime > 19"
1553
+ metric = maf.ColorSlope2NightMetric()
1554
+ summaryMetrics_cs = [maf.SumMetric()]
1555
+ bundleList.append(
1556
+ maf.MetricBundle(
1557
+ metric,
1558
+ healpixslicer,
1559
+ sql,
1560
+ run_name=runName,
1561
+ display_dict=displayDict,
1562
+ summary_metrics=summaryMetrics_cs,
1563
+ )
1564
+ )
1565
+
1566
+ # XRB metric
1567
+ displayDict["subgroup"] = "XRB"
1568
+ displayDict["order"] = 0
1569
+ displayDict["caption"] = "Number or characterization of XRBs."
1570
+ n_events = 10000
1571
+ xrbslicer = maf.generate_xrb_pop_slicer(n_events=n_events)
1572
+ metric = maf.XRBPopMetric(output_lc=False, mjd0=mjd0)
1573
+ xrb_summaryMetrics = [
1574
+ maf.SumMetric(metric_name="Total detected"),
1575
+ maf.CountMetric(metric_name="Total lightcurves in footprint"),
1576
+ maf.CountMetric(metric_name="Total lightcurves on sky", mask_val=0),
1577
+ maf.MeanMetric(metric_name="Fraction detected in footprint"),
1578
+ maf.MeanMetric(mask_val=0, metric_name="Fraction detected of total"),
1579
+ maf.MedianMetric(metric_name="Median"),
1580
+ maf.MeanMetric(metric_name="Mean"),
1581
+ ]
1582
+
1583
+ bundleList.append(
1584
+ maf.MetricBundle(
1585
+ metric,
1586
+ xrbslicer,
1587
+ "",
1588
+ run_name=runName,
1589
+ summary_metrics=xrb_summaryMetrics,
1590
+ display_dict=displayDict,
1591
+ )
1592
+ )
1593
+
1594
+ #########################
1595
+ #########################
1596
+ # Milky Way
1597
+ #########################
1598
+ #########################
1599
+
1600
+ displayDict = {"group": "Milky Way", "subgroup": ""}
1601
+
1602
+ displayDict["subgroup"] = "N stars"
1603
+ slicer = slicers.HealpixSlicer(nside=nside, use_cache=False)
1604
+ sum_stats = [metrics.SumMetric(metric_name="Total N Stars, crowding")]
1605
+ for f in filterlist:
1606
+ stellar_map = maps.StellarDensityMap(filtername=f)
1607
+ displayDict["order"] = filterorders[f]
1608
+ displayDict["caption"] = (
1609
+ "Number of stars in %s band with an measurement uncertainty due to crowding "
1610
+ "of less than 0.2 mag" % f
1611
+ )
1612
+ # Configure the NstarsMetric - note 'filtername' refers to the
1613
+ # filter in which to evaluate crowding
1614
+ metric = metrics.NstarsMetric(
1615
+ crowding_error=0.2,
1616
+ filtername=f,
1617
+ ignore_crowding=False,
1618
+ maps=[],
1619
+ )
1620
+ plotDict = {"n_ticks": 5, "log_scale": True, "color_min": 100}
1621
+ bundle = mb.MetricBundle(
1622
+ metric,
1623
+ slicer,
1624
+ filtersqls[f],
1625
+ run_name=runName,
1626
+ summary_metrics=sum_stats,
1627
+ plot_funcs=subsetPlots,
1628
+ plot_dict=plotDict,
1629
+ display_dict=displayDict,
1630
+ maps_list=[stellar_map],
1631
+ )
1632
+ bundleList.append(bundle)
1633
+
1634
+ slicer = slicers.HealpixSlicer(nside=nside, use_cache=False)
1635
+ sum_stats = [metrics.SumMetric(metric_name="Total N Stars, no crowding")]
1636
+ for f in filterlist:
1637
+ stellar_map = maps.StellarDensityMap(filtername=f)
1638
+ displayDict["order"] = filterorders[f]
1639
+ displayDict["caption"] = (
1640
+ "Number of stars in %s band with an measurement uncertainty "
1641
+ "of less than 0.2 mag, not considering crowding" % f
1642
+ )
1643
+ # Configure the NstarsMetric - note 'filtername' refers to the
1644
+ # filter in which to evaluate crowding
1645
+ metric = metrics.NstarsMetric(
1646
+ crowding_error=0.2,
1647
+ filtername=f,
1648
+ ignore_crowding=True,
1649
+ metric_name="Nstars_no_crowding",
1650
+ maps=[],
1651
+ )
1652
+ plotDict = {"n_ticks": 5, "log_scale": True, "color_min": 100}
1653
+ bundle = mb.MetricBundle(
1654
+ metric,
1655
+ slicer,
1656
+ filtersqls[f],
1657
+ run_name=runName,
1658
+ summary_metrics=sum_stats,
1659
+ plot_funcs=subsetPlots,
1660
+ plot_dict=plotDict,
1661
+ display_dict=displayDict,
1662
+ maps_list=[stellar_map],
1663
+ )
1664
+ bundleList.append(bundle)
1665
+
1666
+ # Brown Dwarf Volume
1667
+ displayDict["subgroup"] = "Brown Dwarf"
1668
+ displayDict["order"] = 0
1669
+ l7_bd_mags = {"i": 20.09, "z": 18.18, "y": 17.13}
1670
+ displayDict["caption"] = (
1671
+ f"The expected maximum distance at which an L7 brown dwarf with magnitude {l7_bd_mags} "
1672
+ f"would have a parallax SNR of 10.0. The summary statistic represents the volume enclosed by "
1673
+ f"the result of this metric (BDParallaxMetric)."
1674
+ )
1675
+ sum_stats = [metrics.VolumeSumMetric(nside=nside)]
1676
+ metric = metrics.BDParallaxMetric(mags=l7_bd_mags, metric_name="Brown Dwarf, L7")
1677
+ sql = ""
1678
+ plotDict = {}
1679
+ bundleList.append(
1680
+ mb.MetricBundle(
1681
+ metric,
1682
+ healpixslicer,
1683
+ sql,
1684
+ plot_dict=plotDict,
1685
+ summary_metrics=sum_stats,
1686
+ display_dict=displayDict,
1687
+ run_name=runName,
1688
+ )
1689
+ )
1690
+
1691
+ l4_bd_mags = {"i": 18.35, "z": 16.68, "y": 15.66}
1692
+ displayDict["caption"] = (
1693
+ f"The expected maximum distance at which an L4 brown dwarf with magnitude {l4_bd_mags} "
1694
+ f"would have a parallax SNR of 10.0. The summary statistic represents the total volume enclosed "
1695
+ f"by the result of this metric (BDParallaxMetric)."
1696
+ )
1697
+ metric = metrics.BDParallaxMetric(mags=l4_bd_mags, metric_name="Brown Dwarf, L4")
1698
+ bundleList.append(
1699
+ mb.MetricBundle(
1700
+ metric,
1701
+ healpixslicer,
1702
+ sql,
1703
+ plot_dict=plotDict,
1704
+ summary_metrics=sum_stats,
1705
+ display_dict=displayDict,
1706
+ run_name=runName,
1707
+ )
1708
+ )
1709
+
1710
+ displayDict["subgroup"] = "Young Stellar Objects"
1711
+ displayDict["caption"] = (
1712
+ "The number of expected Young Stellar Objects with age t<10 Myr and "
1713
+ "mass >0.3 solar masses, using coadded depths in g, r and i bands."
1714
+ )
1715
+ # The underlying dustmap is nside=64, but can be resampled
1716
+ nside_yso = 64
1717
+ dustmap3d = maps.DustMap3D(nside=nside_yso)
1718
+ sql = ""
1719
+ # Let's plug in the magnitudes for one type
1720
+ metric = maf.maf_contrib.NYoungStarsMetric()
1721
+ slicer = maf.slicers.HealpixSlicer(nside=nside_yso, use_cache=False)
1722
+ summaryStats = [maf.metrics.SumMetric()]
1723
+ plotDict = {"log_scale": True, "color_min": 1}
1724
+ bundleList.append(
1725
+ maf.metric_bundles.MetricBundle(
1726
+ metric,
1727
+ slicer,
1728
+ sql,
1729
+ maps_list=[dustmap3d],
1730
+ plot_dict=plotDict,
1731
+ summary_metrics=summaryStats,
1732
+ run_name=runName,
1733
+ display_dict=displayDict,
1734
+ )
1735
+ )
1736
+
1737
+ # Local Volume Dwarf Satellites
1738
+ displayDict["group"] = "Local Volume"
1739
+ displayDict["subgroup"] = "LV dwarf satellites"
1740
+ displayDict["order"] = 0
1741
+ # First the known dwarf satellite galaxies
1742
+ displayDict["caption"] = (
1743
+ "Predicted magnitude detection limit (including stellar density and "
1744
+ "star-galaxy separation) at the location of known LV dwarf galaxies. "
1745
+ )
1746
+ i_starMap = maf.maps.StellarDensityMap(filtername="i")
1747
+ lv_slicer = maf.maf_contrib.generate_known_lv_dwarf_slicer()
1748
+ lv_metric = maf.maf_contrib.LVDwarfsMetric()
1749
+ sqlconstraint = "(filter = 'i' OR filter = 'g')"
1750
+ info_label = "gi"
1751
+ cutoff = -6.4
1752
+ summary_metrics = [
1753
+ maf.metrics.CountBeyondThreshold(lower_threshold=cutoff, metric_name=f"Total detected {cutoff}"),
1754
+ maf.metrics.CountBeyondThreshold(lower_threshold=-7.0, metric_name="Total detected -7.0"),
1755
+ ]
1756
+ plotDict = {"n_ticks": 7}
1757
+ bundle = maf.MetricBundle(
1758
+ lv_metric,
1759
+ lv_slicer,
1760
+ sqlconstraint,
1761
+ maps_list=[i_starMap],
1762
+ summary_metrics=summary_metrics,
1763
+ info_label=info_label,
1764
+ display_dict=displayDict,
1765
+ plot_dict=plotDict,
1766
+ )
1767
+ bundleList.append(bundle)
1768
+
1769
+ displayDict["order"] += 1
1770
+ displayDict["caption"] = (
1771
+ "Predicted magnitude detection limit (including stellar density and "
1772
+ "star-galaxy separation), over the whole sky to a distance of 4 Mpc."
1773
+ )
1774
+ lv_metric2 = maf.maf_contrib.LVDwarfsMetric(distlim=4.0 * u.Mpc) # for a distance limit, healpix map
1775
+ dustmap = maf.maps.DustMap(nside=32)
1776
+ lv_healpix_slicer = maf.slicers.HealpixSlicer(nside=32, use_cache=False)
1777
+ summary_area = maf.AreaThresholdMetric(lower_threshold=cutoff, metric_name=f"Area M_v>{cutoff}")
1778
+ bundle = maf.MetricBundle(
1779
+ lv_metric2,
1780
+ lv_healpix_slicer,
1781
+ sqlconstraint,
1782
+ maps_list=[i_starMap, dustmap],
1783
+ info_label=info_label,
1784
+ display_dict=displayDict,
1785
+ summary_metrics=summary_area,
1786
+ plot_dict=plotDict,
1787
+ )
1788
+ bundleList.append(bundle)
1789
+
1790
+ displayDict["order"] += 1
1791
+ displayDict["caption"] = (
1792
+ "Predicted magnitude detection limit (including stellar density and "
1793
+ "star-galaxy separation), over the southern celestial pole,"
1794
+ "to a distance of 0.1 Mpc."
1795
+ )
1796
+ sqlconstraint = "(filter = 'i' OR filter = 'g') and fieldDec < -60"
1797
+ info_label = "gi SCP"
1798
+ lv_metric3 = maf.maf_contrib.LVDwarfsMetric(distlim=0.1 * u.Mpc) # for a distance limit, healpix map
1799
+ summary_area = maf.metrics.AreaThresholdMetric(lower_threshold=0.0, metric_name="Area M_v>0.0")
1800
+ summary_median = maf.metrics.MedianMetric()
1801
+ bundle = maf.MetricBundle(
1802
+ lv_metric3,
1803
+ lv_healpix_slicer,
1804
+ sqlconstraint,
1805
+ maps_list=[i_starMap, dustmap],
1806
+ info_label=info_label,
1807
+ display_dict=displayDict,
1808
+ plot_dict=plotDict,
1809
+ summary_metrics=[summary_area, summary_median],
1810
+ )
1811
+ bundleList.append(bundle)
1812
+
1813
+ #########################
1814
+ #########################
1815
+ # Per year things
1816
+ #########################
1817
+ #########################
1818
+
1819
+ plotDict = {}
1820
+ night_cuttoffs = np.arange(1, 11, 1) * 365.25
1821
+ slicer = slicers.HealpixSlicer(nside=nside)
1822
+ for i, cuttoff in enumerate(night_cuttoffs):
1823
+ for filtername in "ugrizy":
1824
+ sql = "night<%i and filter='%s'" % (cuttoff, filtername)
1825
+ metric = metrics.Coaddm5Metric(metric_name="coadd %s, year<%i" % (filtername, i + 1))
1826
+ displayDict = {"group": "Per year", "subgroup": "Coadds"}
1827
+ bundle = mb.MetricBundle(
1828
+ metric,
1829
+ slicer,
1830
+ sql,
1831
+ run_name=runName,
1832
+ summary_metrics=standardStats,
1833
+ plot_funcs=subsetPlots,
1834
+ plot_dict=plotDict,
1835
+ display_dict=displayDict,
1836
+ )
1837
+ bundleList.append(bundle)
1838
+
1839
+ metric = metrics.SnrWeightedMetric(
1840
+ col="seeingFwhmEff",
1841
+ metric_name="SNR-weighted FWHMeff %s, year<%i" % (filtername, i + 1),
1842
+ )
1843
+ displayDict = {"group": "Per year", "subgroup": "Seeing"}
1844
+ bundle = mb.MetricBundle(
1845
+ metric,
1846
+ slicer,
1847
+ sql,
1848
+ run_name=runName,
1849
+ summary_metrics=standardStats,
1850
+ plot_funcs=subsetPlots,
1851
+ plot_dict=plotDict,
1852
+ display_dict=displayDict,
1853
+ )
1854
+ bundleList.append(bundle)
1855
+
1856
+ #########################
1857
+ #########################
1858
+ # Scaling numbers
1859
+ #########################
1860
+ #########################
1861
+
1862
+ displayDict = {"group": "Scaling Numbers", "subgroup": ""}
1863
+ displayDict["subgroup"] = "N gals"
1864
+ sql = "filter='i'"
1865
+ metric = metrics.NgalScaleMetric()
1866
+ # galaxy counting uses dustmap
1867
+ slicer = slicers.HealpixSlicer(nside=nside, use_cache=False)
1868
+ displayDict["caption"] = (
1869
+ "Approximate number of resolvable galaxies in i band, scaled by the "
1870
+ "coadded depth and median seeing. A dust and magnitude cut has been applied."
1871
+ )
1872
+ bundle = mb.MetricBundle(
1873
+ metric,
1874
+ slicer,
1875
+ sql,
1876
+ run_name=runName,
1877
+ summary_metrics=[metrics.SumMetric()],
1878
+ plot_funcs=subsetPlots,
1879
+ plot_dict=plotDict,
1880
+ display_dict=displayDict,
1881
+ )
1882
+ bundleList.append(bundle)
1883
+
1884
+ displayDict["subgroup"] = "Lightcurve Pts"
1885
+ metric = metrics.NlcPointsMetric(nside=nside)
1886
+ # NlcPoints metric uses star density maps
1887
+ slicer = slicers.HealpixSlicer(nside=nside, use_cache=False)
1888
+ displayDict["caption"] = (
1889
+ "Approximate number of expected stellar measurements (nstars * nobs) "
1890
+ "in all filters, where the limiting magnitude for at least 10 visits "
1891
+ "is fainter than 21st magnitude, using a TRILEGAL stellar density map."
1892
+ )
1893
+ bundle = mb.MetricBundle(
1894
+ metric,
1895
+ slicer,
1896
+ None,
1897
+ run_name=runName,
1898
+ summary_metrics=[metrics.SumMetric()],
1899
+ plot_funcs=subsetPlots,
1900
+ plot_dict=plotDict,
1901
+ display_dict=displayDict,
1902
+ )
1903
+ bundleList.append(bundle)
1904
+
1905
+ # Set the run_name for all bundles and return the bundleDict.
1906
+ for b in bundleList:
1907
+ b.set_run_name(runName)
1908
+ bundleDict = mb.make_bundles_dict_from_list(bundleList)
1909
+
1910
+ return bundleDict