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,834 @@
1
+ __all__ = ("make_bundles_dict_from_list", "MetricBundleGroup")
2
+
3
+ import os
4
+ import sys
5
+ import warnings
6
+ from collections import OrderedDict
7
+
8
+ import matplotlib.pyplot as plt
9
+ import numpy as np
10
+ import numpy.ma as ma
11
+ import tqdm
12
+
13
+ import rubin_sim.maf.db as db
14
+ import rubin_sim.maf.utils as utils
15
+ from rubin_sim.maf.plots import PlotHandler
16
+
17
+ from .metric_bundle import MetricBundle, create_empty_metric_bundle
18
+
19
+
20
+ def make_bundles_dict_from_list(bundle_list):
21
+ """Utility to convert a list of MetricBundles into a dictionary,
22
+ keyed by the file_root names.
23
+
24
+ Raises an exception if the file_root duplicates another metricBundle.
25
+ (Note this should alert to potential cases of filename duplication).
26
+
27
+ Parameters
28
+ ----------
29
+ bundle_list : `list` [`MetricBundles`]
30
+ List of metric bundles to convert into a dict.
31
+ """
32
+ b_dict = {}
33
+ for b in bundle_list:
34
+ if b.file_root in b_dict:
35
+ raise NameError("More than one metric_bundle is using the same file_root, %s" % (b.file_root))
36
+ b_dict[b.file_root] = b
37
+ return b_dict
38
+
39
+
40
+ class MetricBundleGroup:
41
+ """Calculate all values for a group of MetricBundles.
42
+
43
+ Parameters
44
+ ----------
45
+ bundle_dict : `dict` or `list` [`MetricBundles`]
46
+ Individual MetricBundles should be placed into a dictionary,
47
+ and then passed to the MetricBundleGroup.
48
+ The dictionary keys can then be used to identify MetricBundles
49
+ if needed -- and to identify new MetricBundles which could be
50
+ created if 'reduce' functions are run on a particular MetricBundle.
51
+ A bundle_dict can be conveniently created from a list of MetricBundles
52
+ using makeBundlesDictFromList (done automatically if a list is passed).
53
+ db_con : `str` or database connection object
54
+ A str that is the path to a sqlite3 file or a database object
55
+ that can be used by pandas.read_sql.
56
+ Advanced use: It is possible to set this to None, in which case
57
+ data should be passed directly to the runCurrent method
58
+ (and runAll should not be used).
59
+ out_dir : `str`, opt
60
+ Directory to save the metric results. Default is the current directory.
61
+ results_db : `ResultsDb`, opt
62
+ A results database to store summary stat information.
63
+ If not specified, one will be created in the out_dir.
64
+ This database saves information about the metrics calculated,
65
+ including their summary statistics.
66
+ verbose : `bool`, opt
67
+ Flag to turn on/off verbose feedback.
68
+ save_early : `bool`, opt
69
+ If True, metric values will be saved immediately after
70
+ they are first calculated (to prevent data loss) as well as after
71
+ summary statistics are calculated.
72
+ If False, metric values will only be saved after summary statistics
73
+ are calculated.
74
+ db_table : `str`, opt
75
+ The name of the table in the db_obj to query for data.
76
+ For modern opsim outputs, this table is `observations` (default None).
77
+
78
+ Notes
79
+ -----
80
+ The MetricBundleGroup will query data from a single database table
81
+ (for multiple constraints), use that data to calculate metric values
82
+ for multiple slicers, and calculate summary statistics and
83
+ generate plots for all metrics included in
84
+ the dictionary passed to the MetricBundleGroup.
85
+
86
+ We calculate the metric values here, rather than in the
87
+ individual MetricBundles, because it is much more efficient to step
88
+ through a slicer once (and calculate all the relevant metric values
89
+ at each point) than it is to repeat this process multiple times.
90
+
91
+ The MetricBundleGroup also determines how to efficiently group
92
+ the MetricBundles to reduce the number of sql queries of the database,
93
+ grabbing larger chunks of data at once.
94
+ """
95
+
96
+ def __init__(
97
+ self,
98
+ bundle_dict,
99
+ db_con,
100
+ out_dir=".",
101
+ results_db=None,
102
+ verbose=False,
103
+ save_early=True,
104
+ db_table=None,
105
+ ):
106
+ """Set up the MetricBundleGroup."""
107
+ if isinstance(bundle_dict, list):
108
+ bundle_dict = make_bundles_dict_from_list(bundle_dict)
109
+ # Print occasional messages to screen.
110
+ self.verbose = verbose
111
+ # Save metric results as soon as possible (in case of crash).
112
+ self.save_early = save_early
113
+ # Check for output directory, create it if needed.
114
+ self.out_dir = out_dir
115
+ if not os.path.isdir(self.out_dir):
116
+ os.makedirs(self.out_dir)
117
+
118
+ # Do some type checking on the MetricBundle dictionary.
119
+ if not isinstance(bundle_dict, dict):
120
+ raise ValueError("bundleDict should be a dictionary containing MetricBundle objects.")
121
+ for b in bundle_dict.values():
122
+ if not isinstance(b, MetricBundle):
123
+ raise ValueError("bundleDict should contain only MetricBundle objects.")
124
+ # Identify the series of constraints.
125
+ self.constraints = list(set([b.constraint for b in bundle_dict.values()]))
126
+ # Set the bundleDict (all bundles, with all constraints)
127
+ self.bundle_dict = bundle_dict
128
+
129
+ self.db_obj = db_con
130
+ # Set the table we're going to be querying.
131
+ self.db_table = db_table
132
+
133
+ # Check the results_db (optional).
134
+ if results_db is not None:
135
+ if not isinstance(results_db, db.ResultsDb):
136
+ raise ValueError("results_db should be an ResultsDb object")
137
+ self.results_db = results_db
138
+
139
+ # Dict to keep track of what's been run:
140
+ self.has_run = {}
141
+ for bk in bundle_dict:
142
+ self.has_run[bk] = False
143
+
144
+ def _check_compatible(self, metric_bundle1, metric_bundle2):
145
+ """Check if two MetricBundles are "compatible".
146
+
147
+ Parameters
148
+ ----------
149
+ metric_bundle1 : `MetricBundle`
150
+ metric_bundle2 : `MetricBundle`
151
+
152
+ Returns
153
+ -------
154
+ match : `bool`
155
+
156
+ Notes
157
+ -----
158
+ Compatible indicates that the sql constraints, the slicers,
159
+ and the maps are the same, and
160
+ that the stackers do not interfere with each other
161
+ (i.e. are not trying to set the same column in different ways).
162
+ Returns True if the MetricBundles are compatible, False if not.
163
+ """
164
+ if metric_bundle1.constraint != metric_bundle2.constraint:
165
+ return False
166
+ if metric_bundle1.slicer != metric_bundle2.slicer:
167
+ return False
168
+ if metric_bundle1.maps_list.sort() != metric_bundle2.maps_list.sort():
169
+ return False
170
+ for stacker in metric_bundle1.stacker_list:
171
+ for stacker2 in metric_bundle2.stacker_list:
172
+ # If the stackers have different names, that's OK,
173
+ # and if they are identical, that's ok.
174
+ if (stacker.__class__.__name__ == stacker2.__class__.__name__) & (stacker != stacker2):
175
+ return False
176
+ # But if we got this far, everything matches.
177
+ return True
178
+
179
+ def _find_compatible_lists(self):
180
+ """Find sets of compatible metricBundles from the currentBundleDict."""
181
+ # CompatibleLists stores a list of lists;
182
+ # each (nested) list contains the bundleDict _keys_
183
+ # of a compatible set of metricBundles.
184
+ compatible_lists = []
185
+ for k, b in self.current_bundle_dict.items():
186
+ found_compatible = False
187
+ for compatible_list in compatible_lists:
188
+ comparison_metric_bundle_key = compatible_list[0]
189
+ compatible = self._check_compatible(self.bundle_dict[comparison_metric_bundle_key], b)
190
+ if compatible:
191
+ # Must compare all metricBundles in each subset
192
+ # (if they are a potential match),
193
+ # as the stackers could be different
194
+ # (and one could be incompatible,
195
+ # not necessarily the first)
196
+ for comparison_metric_bundle_key in compatible_list[1:]:
197
+ compatible = self._check_compatible(self.bundle_dict[comparison_metric_bundle_key], b)
198
+ if not compatible:
199
+ # If we find one which is not compatible,
200
+ # stop and go on to the
201
+ # next subset list.
202
+ break
203
+ # Otherwise, we reached the end of the subset
204
+ # and they were all compatible.
205
+ found_compatible = True
206
+ compatible_list.append(k)
207
+ if not found_compatible:
208
+ # Didn't find a pre-existing compatible set; make a new one.
209
+ compatible_lists.append(
210
+ [
211
+ k,
212
+ ]
213
+ )
214
+ self.compatible_lists = compatible_lists
215
+
216
+ def run_all(self, clear_memory=False, plot_now=False, plot_kwargs=None):
217
+ """Calculates metric values, then runs reduce functions and summary
218
+ statistics for all MetricBundles, over all constraints.
219
+
220
+ Parameters
221
+ ----------
222
+ clear_memory : `bool`, optional
223
+ If True, deletes metric values from memory after running
224
+ each constraint group.
225
+ plot_now : `bool`, optional
226
+ If True, plots the metric values immediately after calculation.
227
+ plot_kwargs : `bool`, optional
228
+ kwargs to pass to plotCurrent.
229
+ """
230
+ for constraint in self.constraints:
231
+ # Set the 'currentBundleDict' which is a dictionary of the
232
+ # metricBundles which match this constraint.
233
+ self.run_current(
234
+ constraint,
235
+ clear_memory=clear_memory,
236
+ plot_now=plot_now,
237
+ plot_kwargs=plot_kwargs,
238
+ )
239
+
240
+ def set_current(self, constraint):
241
+ """Utility to set the currentBundleDict
242
+ (i.e. a set of metricBundles with the same SQL constraint).
243
+
244
+ Parameters
245
+ ----------
246
+ constraint : `str`
247
+ The subset of MetricBundles with metricBundle.constraint ==
248
+ constraint will be included in a subset identified as the
249
+ currentBundleDict.
250
+ These are the active metrics to be calculated and plotted, etc.
251
+
252
+ Notes
253
+ -----
254
+ This is useful, for the context of running only a specific set
255
+ of metric bundles so that the user can provide `sim_data` directly.
256
+ """
257
+ if constraint is None:
258
+ constraint = ""
259
+ self.current_bundle_dict = {}
260
+ for k, b in self.bundle_dict.items():
261
+ if b.constraint == constraint:
262
+ self.current_bundle_dict[k] = b
263
+ # Build list of all the columns needed from the database.
264
+ self.db_cols = []
265
+ for b in self.current_bundle_dict.values():
266
+ self.db_cols.extend(b.db_cols)
267
+ self.db_cols = list(set(self.db_cols))
268
+
269
+ def run_current(
270
+ self,
271
+ constraint,
272
+ sim_data=None,
273
+ clear_memory=False,
274
+ plot_now=False,
275
+ plot_kwargs=None,
276
+ ):
277
+ """Calculates the metric values, then runs reduce functions and
278
+ summary statistics for metrics in the current set only
279
+ (see self.setCurrent).
280
+
281
+ Parameters
282
+ ----------
283
+ constraint : `str`
284
+ constraint to use to set the currently active metrics
285
+ sim_data : `np.ndarray`, opt
286
+ If simData is not None, then this numpy structured array is used
287
+ instead of querying data from the dbObj.
288
+ clear_memory : `bool`, opt
289
+ If True, metric values are deleted from memory after they are
290
+ calculated (and saved to disk).
291
+ plot_now : `bool`, opt
292
+ Plot immediately after calculating metric values
293
+ (instead of the usual procedure, which is to plot after metric
294
+ values are calculated for all constraints).
295
+ plot_kwargs : kwargs, opt
296
+ Plotting kwargs to pass to plotCurrent.
297
+
298
+ Notes
299
+ -----
300
+ This is useful, for the context of running only a specific set
301
+ of metric bundles so that the user can provide `sim_data` directly.
302
+ """
303
+ self.set_current(constraint)
304
+
305
+ # Can pass simData directly (if had other method for getting data)
306
+ if sim_data is not None:
307
+ self.sim_data = sim_data
308
+
309
+ else:
310
+ self.sim_data = None
311
+ # Query for the data.
312
+ try:
313
+ self.get_data(constraint)
314
+ except UserWarning:
315
+ warnings.warn("No data matching constraint %s" % constraint)
316
+ metrics_skipped = []
317
+ for b in self.current_bundle_dict.values():
318
+ metrics_skipped.append(
319
+ "%s : %s : %s" % (b.metric.name, b.info_label, b.slicer.slicer_name)
320
+ )
321
+ warnings.warn(" This means skipping metrics %s" % metrics_skipped)
322
+ return
323
+ except ValueError:
324
+ warnings.warn(
325
+ "One or more of the columns requested from the database was not available."
326
+ + " Skipping constraint %s" % constraint
327
+ )
328
+ metrics_skipped = []
329
+ for b in self.current_bundle_dict.values():
330
+ metrics_skipped.append(
331
+ "%s : %s : %s" % (b.metric.name, b.info_label, b.slicer.slicer_name)
332
+ )
333
+ warnings.warn(" This means skipping metrics %s" % metrics_skipped)
334
+ return
335
+
336
+ # Find compatible subsets of the MetricBundle dictionary,
337
+ # which can be run/metrics calculated/ together.
338
+ self._find_compatible_lists()
339
+
340
+ for compatible_list in self.compatible_lists:
341
+ if self.verbose:
342
+ print("Running: ", compatible_list)
343
+ self._run_compatible(compatible_list)
344
+ if self.verbose:
345
+ print("Completed metric generation.")
346
+ for key in compatible_list:
347
+ self.has_run[key] = True
348
+ # Run the reduce methods.
349
+ if self.verbose:
350
+ print("Running reduce methods.")
351
+ self.reduce_current()
352
+ # Run the summary statistics.
353
+ if self.verbose:
354
+ print("Running summary statistics.")
355
+ self.summary_current()
356
+ if self.verbose:
357
+ print("Completed.")
358
+ if plot_now:
359
+ if plot_kwargs is None:
360
+ self.plot_current()
361
+ else:
362
+ self.plot_current(**plot_kwargs)
363
+ # Optionally: clear results from memory.
364
+ if clear_memory:
365
+ for b in self.current_bundle_dict.values():
366
+ b.metric_values = None
367
+ if self.verbose:
368
+ print("Deleted metric_values from memory.")
369
+
370
+ def get_data(self, constraint):
371
+ """Query the data from the database.
372
+
373
+ The currently bundleDict should generally be set
374
+ before calling getData (using setCurrent).
375
+
376
+ Parameters
377
+ ----------
378
+ constraint : `str`
379
+ The constraint for the currently active set of MetricBundles.
380
+ """
381
+ if self.verbose:
382
+ if constraint == "":
383
+ print("Querying table %s with no constraint for columns %s." % (self.db_table, self.db_cols))
384
+ else:
385
+ print(
386
+ "Querying table %s with constraint %s for columns %s"
387
+ % (self.db_table, constraint, self.db_cols)
388
+ )
389
+ # Note that we do NOT run the stackers at this point
390
+ # (this must be done in each 'compatible' group).
391
+ self.sim_data = utils.get_sim_data(
392
+ self.db_obj,
393
+ constraint,
394
+ self.db_cols,
395
+ table_name=self.db_table,
396
+ )
397
+
398
+ if self.verbose:
399
+ print("Found %i visits" % (self.sim_data.size))
400
+
401
+ def _run_compatible(self, compatible_list):
402
+ """Runs a set of 'compatible' metric_bundles in the MetricBundleGroup
403
+ dictionary identified by 'compatible_list' keys.
404
+
405
+ A compatible list of MetricBundles is a subset of the
406
+ currentBundleDict.
407
+ The currentBundleDict == set of MetricBundles with the same constraint.
408
+ The compatibleBundles == set of MetricBundles with the same constraint,
409
+ AND the same slicer, the same maps applied to the slicer,
410
+ and stackers which do not clobber each other's data.
411
+
412
+ This is where the work of calculating the metric values is done.
413
+ """
414
+
415
+ if len(self.sim_data) == 0:
416
+ return
417
+
418
+ # Grab a dictionary representation of this subset of the dictionary,
419
+ # for easier iteration.
420
+ b_dict = {key: self.current_bundle_dict.get(key) for key in compatible_list}
421
+
422
+ # Find the unique stackers and maps.
423
+ # These are already "compatible" (as id'd by compatible_list).
424
+ uniq_stackers = []
425
+ all_stackers = []
426
+ uniq_maps = []
427
+ all_maps = []
428
+ for b in b_dict.values():
429
+ all_stackers += b.stacker_list
430
+ all_maps += b.maps_list
431
+ for s in all_stackers:
432
+ if s not in uniq_stackers:
433
+ uniq_stackers.append(s)
434
+ for m in all_maps:
435
+ if m not in uniq_maps:
436
+ uniq_maps.append(m)
437
+
438
+ # Run stackers.
439
+ for stacker in uniq_stackers:
440
+ # Note that stackers will clobber previously existing columns
441
+ self.sim_data = stacker.run(self.sim_data, override=True)
442
+
443
+ # Pull out one of the slicers to use as our 'slicer'.
444
+ # This will be forced back into all of the metricBundles
445
+ # at the end (so that they track the same info_label such as the
446
+ # slice_points, in case the same actual object wasn't used).
447
+ slicer = list(b_dict.values())[0].slicer
448
+ slicer.setup_slicer(self.sim_data, maps=uniq_maps)
449
+ # Copy the slicer (after setup) back into the individual metricBundles.
450
+ if slicer.slicer_name != "HealpixSlicer" or slicer.slicer_name != "UniSlicer":
451
+ for b in b_dict.values():
452
+ b.slicer = slicer
453
+
454
+ # Set up (masked) arrays to store metric data in each metricBundle.
455
+ for b in b_dict.values():
456
+ b._setup_metric_values()
457
+
458
+ # Set up an ordered dictionary to be the cache if needed:
459
+ # (Currently using OrderedDict,
460
+ # it might be faster to use 2 regular Dicts instead)
461
+ if slicer.cache_size > 0:
462
+ cache_dict = OrderedDict()
463
+ cache = True
464
+ else:
465
+ cache = False
466
+ # Run through all slicepoints and calculate metrics.
467
+ if self.verbose:
468
+ slicer_iter = tqdm.tqdm(
469
+ slicer,
470
+ desc="Processing slices",
471
+ ncols=79,
472
+ file=sys.stdout,
473
+ )
474
+ else:
475
+ slicer_iter = slicer
476
+
477
+ for slice_i in slicer_iter:
478
+ i = slice_i["slice_point"]["sid"]
479
+ slicedata = self.sim_data[slice_i["idxs"]]
480
+ if len(slicedata) == 0:
481
+ # No data at this slice_point. Mask data values.
482
+ for b in b_dict.values():
483
+ b.metric_values.mask[i] = True
484
+ else:
485
+ # There is data! Should we use our data cache?
486
+ if cache:
487
+ # Make the data idxs hashable.
488
+ cache_key = frozenset(slice_i["idxs"])
489
+ # If key exists, set flag to use it, otherwise add it
490
+ if cache_key in cache_dict:
491
+ use_cache = True
492
+ cache_val = cache_dict[cache_key]
493
+ # Move this value to the end of the OrderedDict
494
+ del cache_dict[cache_key]
495
+ cache_dict[cache_key] = cache_val
496
+ else:
497
+ cache_dict[cache_key] = i
498
+ use_cache = False
499
+ for b in b_dict.values():
500
+ if use_cache:
501
+ b.metric_values.data[i] = b.metric_values.data[cache_dict[cache_key]]
502
+ else:
503
+ b.metric_values.data[i] = b.metric.run(
504
+ slicedata, slice_point=slice_i["slice_point"]
505
+ )
506
+ # If we are above the cache size,
507
+ # drop the oldest element from the cache dict.
508
+ if len(cache_dict) > slicer.cache_size:
509
+ del cache_dict[list(cache_dict.keys())[0]]
510
+
511
+ # Not using memoize, just calculate things normally
512
+ else:
513
+ for b in b_dict.values():
514
+ try:
515
+ b.metric_values.data[i] = b.metric.run(
516
+ slicedata, slice_point=slice_i["slice_point"]
517
+ )
518
+ except BaseException as e:
519
+ print(f"Failed at slice_point {slice_i}, sid {i}")
520
+ raise e
521
+ # Mask data where metrics could not be computed
522
+ # (according to metric bad value).
523
+ for b in b_dict.values():
524
+ if b.metric_values.dtype.name == "object":
525
+ for ind, val in enumerate(b.metric_values.data):
526
+ if val is b.metric.badval:
527
+ b.metric_values.mask[ind] = True
528
+ else:
529
+ # For some reason, this doesn't work for dtype=object arrays.
530
+ b.metric_values.mask = np.where(
531
+ b.metric_values.data == b.metric.badval, True, b.metric_values.mask
532
+ )
533
+
534
+ # Save data to disk as we go (just failsafe).
535
+ if self.save_early:
536
+ for b in b_dict.values():
537
+ b.write(out_dir=self.out_dir, results_db=self.results_db)
538
+ else:
539
+ # Just write the metric run information to the results_db
540
+ for b in b_dict.values():
541
+ b.write_db(results_db=self.results_db)
542
+
543
+ def reduce_all(self, update_summaries=True):
544
+ """Run the reduce methods for all metrics in bundleDict.
545
+
546
+ Running this method, for all MetricBundles at once,
547
+ assumes that clearMemory was False.
548
+
549
+ Parameters
550
+ ----------
551
+ update_summaries : `bool`, optional
552
+ If True, summary metrics are removed from the top-level
553
+ (non-reduced) MetricBundle. Usually this should be True,
554
+ as summary metrics are generally intended to run on the simpler
555
+ data produced by reduce metrics.
556
+ """
557
+ for constraint in self.constraints:
558
+ self.set_current(constraint)
559
+ self.reduce_current(update_summaries=update_summaries)
560
+
561
+ def reduce_current(self, update_summaries=True):
562
+ """Run all reduce functions for the metricbundle in the
563
+ currently active set of MetricBundles.
564
+
565
+ Parameters
566
+ ----------
567
+ update_summaries : `bool`, optional
568
+ If True, summary metrics are removed from the top-level
569
+ (non-reduced) MetricBundle. Usually this should be True,
570
+ as summary metrics are generally intended to run on the simpler
571
+ data produced by reduce metrics.
572
+ """
573
+ # Create a temporary dictionary to hold the reduced metricbundles.
574
+ reduce_bundle_dict = {}
575
+ for b in self.current_bundle_dict.values():
576
+ # If there are no reduce functions associated with the metric,
577
+ # skip this metricBundle.
578
+ if len(b.metric.reduce_funcs) > 0:
579
+ # Apply reduce functions, creating a new metricBundle in
580
+ # the process (new metric values).
581
+ for r in b.metric.reduce_funcs:
582
+ newmetricbundle = b.reduce_metric(b.metric.reduce_funcs[r], reduce_func_name=r)
583
+ # Add the new metricBundle to our metricBundleGroup
584
+ # dictionary.
585
+ name = newmetricbundle.metric.name
586
+ if name in self.bundle_dict:
587
+ name = newmetricbundle.file_root
588
+ reduce_bundle_dict[name] = newmetricbundle
589
+ if self.save_early:
590
+ newmetricbundle.write(out_dir=self.out_dir, results_db=self.results_db)
591
+ else:
592
+ newmetricbundle.write_db(results_db=self.results_db)
593
+ # Remove summaryMetrics from top level metricbundle if desired.
594
+ if update_summaries:
595
+ b.summary_metrics = []
596
+ # Add the new metricBundles to the MetricBundleGroup dictionary.
597
+ self.bundle_dict.update(reduce_bundle_dict)
598
+ # And add to to the currentBundleDict too, so we run as part
599
+ # of 'summaryCurrent'.
600
+ self.current_bundle_dict.update(reduce_bundle_dict)
601
+
602
+ def summary_all(self):
603
+ """Run the summary statistics for all metrics in bundleDict.
604
+
605
+ Calculating all summary statistics, for all MetricBundles, at this
606
+ point assumes that clearMemory was False.
607
+ """
608
+ for constraint in self.constraints:
609
+ self.set_current(constraint)
610
+ self.summary_current()
611
+
612
+ def summary_current(self):
613
+ """Run summary statistics on all the metricBundles in the
614
+ currently active set of MetricBundles.
615
+ """
616
+ for b in self.current_bundle_dict.values():
617
+ b.compute_summary_stats(self.results_db)
618
+
619
+ def plot_all(
620
+ self,
621
+ save_figs=True,
622
+ outfile_suffix=None,
623
+ fig_format="pdf",
624
+ dpi=600,
625
+ trim_whitespace=True,
626
+ thumbnail=True,
627
+ closefigs=True,
628
+ ):
629
+ """Generate all the plots for all the metricBundles in bundleDict.
630
+
631
+ Generating all plots, for all MetricBundles,
632
+ At this point, assumes that clearMemory was False.
633
+
634
+ Parameters
635
+ ----------
636
+ savefig : `bool`, optional
637
+ If True, save figures to disk, to self.out_dir directory.
638
+ outfile_suffix : `str`, optional
639
+ Append outfile_suffix to the end of every plot file generated.
640
+ Useful for generating sequential series of images for movies.
641
+ fig_format : `str`, optional
642
+ Matplotlib figure format to use to save to disk.
643
+ dpi : `int`, optional
644
+ DPI for matplotlib figure.
645
+ trim_whitespace : `bool`, optional
646
+ If True, trim additional whitespace from final figures.
647
+ thumbnail : `bool`, optional
648
+ If True, save a small thumbnail jpg version of the output file
649
+ to disk as well. This is useful for show_maf web pages.
650
+ closefigs : `bool`, optional
651
+ Close the matplotlib figures after they are saved to disk.
652
+ If many figures are generated, closing the figures saves
653
+ significant memory.
654
+ """
655
+ for constraint in self.constraints:
656
+ if self.verbose:
657
+ print('Plotting figures with "%s" constraint now.' % (constraint))
658
+
659
+ self.set_current(constraint)
660
+ self.plot_current(
661
+ savefig=save_figs,
662
+ outfile_suffix=outfile_suffix,
663
+ fig_format=fig_format,
664
+ dpi=dpi,
665
+ trim_whitespace=trim_whitespace,
666
+ thumbnail=thumbnail,
667
+ closefigs=closefigs,
668
+ )
669
+
670
+ def plot_current(
671
+ self,
672
+ savefig=True,
673
+ outfile_suffix=None,
674
+ fig_format="pdf",
675
+ dpi=600,
676
+ trim_whitespace=True,
677
+ thumbnail=True,
678
+ closefigs=True,
679
+ ):
680
+ """Generate the plots for the currently active set of MetricBundles.
681
+
682
+ Parameters
683
+ ----------
684
+ savefig : `bool`, optional
685
+ If True, save figures to disk, to self.out_dir directory.
686
+ outfile_suffix : `str`, optional
687
+ Append outfile_suffix to the end of every plot file generated.
688
+ Useful for generating sequential series of images for movies.
689
+ fig_format : `str`, optional
690
+ Matplotlib figure format to use to save to disk.
691
+ dpi : `int`, optional
692
+ DPI for matplotlib figure.
693
+ trim_whitespace : `bool`, optional
694
+ If True, trim additional whitespace from final figures.
695
+ thumbnail : `bool`, optional
696
+ If True, save a small thumbnail jpg version of the output file
697
+ to disk as well. This is useful for show_maf web pages.
698
+ closefigs : `bool`, optional
699
+ Close the matplotlib figures after they are saved to disk.
700
+ If many figures are generated, closing the figures saves
701
+ significant memory.
702
+ """
703
+ plot_handler = PlotHandler(
704
+ out_dir=self.out_dir,
705
+ results_db=self.results_db,
706
+ savefig=savefig,
707
+ fig_format=fig_format,
708
+ dpi=dpi,
709
+ trim_whitespace=trim_whitespace,
710
+ thumbnail=thumbnail,
711
+ )
712
+
713
+ for b in self.current_bundle_dict.values():
714
+ try:
715
+ b.plot(
716
+ plot_handler=plot_handler,
717
+ outfile_suffix=outfile_suffix,
718
+ savefig=savefig,
719
+ )
720
+ except ValueError as ve:
721
+ message = "Plotting failed for metricBundle %s." % (b.file_root)
722
+ message += " Error message: %s" % (ve)
723
+ warnings.warn(message)
724
+ if closefigs:
725
+ plt.close("all")
726
+ if self.verbose:
727
+ print("Plotting complete.")
728
+
729
+ def write_all(self):
730
+ """Save all the MetricBundles to disk.
731
+
732
+ Saving all MetricBundles to disk at this point assumes that
733
+ clearMemory was False.
734
+ """
735
+ for constraint in self.constraints:
736
+ self.set_current(constraint)
737
+ self.write_current()
738
+
739
+ def write_current(self):
740
+ """Save all the MetricBundles in the currently active set to disk."""
741
+ if self.verbose:
742
+ if self.save_early:
743
+ print("Re-saving metric bundles.")
744
+ else:
745
+ print("Saving metric bundles.")
746
+ for b in self.current_bundle_dict.values():
747
+ b.write(out_dir=self.out_dir, results_db=self.results_db)
748
+
749
+ def read_all(self):
750
+ """Attempt to read all MetricBundles from disk.
751
+
752
+ You must set the metrics/slicer/constraint/run_name for a metricBundle
753
+ appropriately, so that the file_root is correct.
754
+ """
755
+ reduce_bundle_dict = {}
756
+ remove_bundles = []
757
+ for b in self.bundle_dict:
758
+ bundle = self.bundle_dict[b]
759
+ filename = os.path.join(self.out_dir, bundle.file_root + ".npz")
760
+ try:
761
+ # Create a temporary metricBundle to read the data into.
762
+ # We are not using "b" directly, as we are trying NOT
763
+ # to override the plot_dict or display_dict.
764
+ tmp_bundle = create_empty_metric_bundle()
765
+ tmp_bundle.read(filename)
766
+ # Copy the tmp_bundle metric_values into bundle.
767
+ bundle.metric_values = tmp_bundle.metric_values
768
+ # And copy the slicer into b, to get slice_points.
769
+ bundle.slicer = tmp_bundle.slicer
770
+ # Copy the summary stats though.
771
+ bundle.summary_values = tmp_bundle.summary_values
772
+ if self.verbose:
773
+ print("Read %s from disk." % (bundle.file_root))
774
+ except IOError:
775
+ warnings.warn("Warning: file %s not found, bundle not restored." % filename)
776
+ remove_bundles.append(b)
777
+
778
+ # Look to see if this is a complex metric,
779
+ # with associated 'reduce' functions, and read those in too.
780
+ if len(bundle.metric.reduce_funcs) > 0:
781
+ orig_metric_name = bundle.metric.name
782
+ for reduce_func in bundle.metric.reduce_funcs.values():
783
+ reduce_name = orig_metric_name + "_" + reduce_func.__name__.replace("reduce", "")
784
+ # Borrow the fileRoot in b (we'll reset it appropriately)
785
+ bundle.metric.name = reduce_name
786
+ bundle._build_file_root()
787
+ filename = os.path.join(self.out_dir, bundle.file_root + ".npz")
788
+ tmp_bundle = create_empty_metric_bundle()
789
+ try:
790
+ tmp_bundle.read(filename)
791
+ # This won't necessarily recreate the plot_dict and
792
+ # display_dict exactly as they would have been made
793
+ # if you calculated the reduce metric from scratch.
794
+ newmetric_bundle = MetricBundle(
795
+ metric=bundle.metric,
796
+ slicer=bundle.slicer,
797
+ constraint=bundle.constraint,
798
+ stacker_list=bundle.stacker_list,
799
+ run_name=bundle.run_name,
800
+ info_label=bundle.info_label,
801
+ plot_dict=bundle.plotDict,
802
+ display_dict=bundle.displayDict,
803
+ summary_metrics=bundle.summary_metrics,
804
+ maps_list=bundle.maps_list,
805
+ file_root=bundle.file_root,
806
+ plot_funcs=bundle.plot_funcs,
807
+ )
808
+ newmetric_bundle.metric.name = reduce_name
809
+ newmetric_bundle.metric_values = ma.copy(tmp_bundle.metric_values)
810
+ newmetric_bundle.summary_values = tmp_bundle.summary_values
811
+ # Add the new metricBundle to metricBundleGroup dict.
812
+ name = newmetric_bundle.metric.name
813
+ if name in self.bundle_dict:
814
+ name = newmetric_bundle.file_root
815
+ reduce_bundle_dict[name] = newmetric_bundle
816
+ if self.verbose:
817
+ print("Read %s from disk." % (newmetric_bundle.file_root))
818
+ except IOError:
819
+ warnings.warn(
820
+ 'Warning: file %s not found, bundle not restored ("reduce" metric).' % filename
821
+ )
822
+
823
+ # Remove summaryMetrics from top level metricbundle.
824
+ bundle.summary_metrics = []
825
+ # Update parent MetricBundle name.
826
+ bundle.metric.name = orig_metric_name
827
+ bundle._build_file_root()
828
+
829
+ # Add the reduce bundles into the bundleDict.
830
+ self.bundle_dict.update(reduce_bundle_dict)
831
+ # And remove the bundles which were not found on disk,
832
+ # so we don't try to make (blank) plots.
833
+ for b in remove_bundles:
834
+ del self.bundle_dict[b]