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,439 @@
1
+ import unittest
2
+
3
+ import healpy as hp
4
+ import matplotlib
5
+ import numpy as np
6
+ import numpy.lib.recfunctions as rfn
7
+ import numpy.ma as ma
8
+
9
+ from rubin_sim.maf.slicers import HealpixSlicer
10
+
11
+ matplotlib.use("Agg")
12
+
13
+
14
+ def make_data_values(
15
+ size=100,
16
+ minval=0.0,
17
+ maxval=1.0,
18
+ ramin=0,
19
+ ramax=2 * np.pi,
20
+ decmin=-np.pi,
21
+ decmax=np.pi,
22
+ random=1172,
23
+ ):
24
+ """Generate a simple array of numbers, evenly arranged between min/max,
25
+ in 1 dimensions (optionally sorted), together with RA/Dec values
26
+ for each data value."""
27
+ data = []
28
+ # Generate data values min - max.
29
+ datavalues = np.arange(0, size, dtype="float")
30
+ datavalues *= (float(maxval) - float(minval)) / (datavalues.max() - datavalues.min())
31
+ datavalues += minval
32
+ rng = np.random.RandomState(random)
33
+ randorder = rng.rand(size)
34
+ randind = np.argsort(randorder)
35
+ datavalues = datavalues[randind]
36
+ datavalues = np.array(list(zip(datavalues)), dtype=[("testdata", "float")])
37
+ data.append(datavalues)
38
+ # Generate RA/Dec values equally spaces on sphere between
39
+ # ramin/max, decmin/max.
40
+ ra = np.arange(0, size, dtype="float")
41
+ ra *= (float(ramax) - float(ramin)) / (ra.max() - ra.min())
42
+ randorder = rng.rand(size)
43
+ randind = np.argsort(randorder)
44
+ ra = ra[randind]
45
+ ra = np.array(list(zip(ra)), dtype=[("ra", "float")])
46
+ data.append(ra)
47
+ v = np.arange(0, size, dtype="float")
48
+ v *= ((np.cos(decmax + np.pi) + 1.0) / 2.0 - (np.cos(decmin + np.pi) + 1.0) / 2.0) / (v.max() - v.min())
49
+ v += (np.cos(decmin + np.pi) + 1.0) / 2.0
50
+ dec = np.arccos(2 * v - 1) - np.pi
51
+ randorder = rng.rand(size)
52
+ randind = np.argsort(randorder)
53
+ dec = dec[randind]
54
+ dec = np.array(list(zip(dec)), dtype=[("dec", "float")])
55
+ data.append(dec)
56
+ # Add in rotation angle
57
+ rot = rng.rand(len(dec)) * 2 * np.pi
58
+ data.append(np.array(rot, dtype=[("rotSkyPos", "float")]))
59
+ mjd = np.arange(len(dec)) * 0.1
60
+ data.append(np.array(mjd, dtype=[("observationStartMJD", "float")]))
61
+ data = rfn.merge_arrays(data, flatten=True, usemask=False)
62
+ return data
63
+
64
+
65
+ def calc_dist_vincenty(ra1, dec1, ra2, dec2):
66
+ """Calculates distance on a sphere using the Vincenty formula.
67
+ Give this function RA/Dec values in radians.
68
+ Returns angular distance(s), in radians.
69
+ Note that since this is all numpy, you could input arrays of RA/Decs."""
70
+ d1 = (np.cos(dec2) * np.sin(ra2 - ra1)) ** 2 + (
71
+ np.cos(dec1) * np.sin(dec2) - np.sin(dec1) * np.cos(dec2) * np.cos(ra2 - ra1)
72
+ ) ** 2
73
+ d1 = np.sqrt(d1)
74
+ d2 = np.sin(dec1) * np.sin(dec2) + np.cos(dec1) * np.cos(dec2) * np.cos(ra2 - ra1)
75
+ D = np.arctan2(d1, d2)
76
+ return D
77
+
78
+
79
+ class TestHealpixSlicerSetup(unittest.TestCase):
80
+ def test_slicertype(self):
81
+ """Test instantiation of slicer sets slicer type as expected."""
82
+ testslicer = HealpixSlicer(nside=16, verbose=False)
83
+ self.assertEqual(testslicer.slicer_name, testslicer.__class__.__name__)
84
+ self.assertEqual(testslicer.slicer_name, "HealpixSlicer")
85
+
86
+ def test_nsides_nbins(self):
87
+ """Test that number of sides passed to slicer produces expected
88
+ number of bins."""
89
+ nsides = [1, 2, 4, 8, 16, 32, 64, 128, 256, 512]
90
+ npixx = [12, 48, 192, 768, 3072, 12288, 49152, 196608, 786432, 3145728]
91
+ for nside, npix in zip(nsides, npixx):
92
+ testslicer = HealpixSlicer(
93
+ nside=nside,
94
+ verbose=False,
95
+ )
96
+ self.assertEqual(testslicer.nslice, npix)
97
+
98
+
99
+ class TestHealpixSlicerEqual(unittest.TestCase):
100
+ def setUp(self):
101
+ self.nside = 16
102
+ self.testslicer = HealpixSlicer(
103
+ nside=self.nside,
104
+ verbose=False,
105
+ lon_col="ra",
106
+ lat_col="dec",
107
+ )
108
+ nvalues = 10000
109
+ self.dv = make_data_values(
110
+ size=nvalues,
111
+ minval=0.0,
112
+ maxval=1.0,
113
+ ramin=0,
114
+ ramax=2 * np.pi,
115
+ decmin=-np.pi,
116
+ decmax=0,
117
+ random=22,
118
+ )
119
+ self.testslicer.setup_slicer(self.dv)
120
+
121
+ def tearDown(self):
122
+ del self.testslicer
123
+ del self.dv
124
+ self.testslicer = None
125
+
126
+ def test_slicer_equivalence(self):
127
+ """Test that slicers are marked equal when appropriate,
128
+ and unequal when appropriate."""
129
+ # Note that they are judged equal based on nsides
130
+ # (not on data in ra/dec spatial tree).
131
+ testslicer2 = HealpixSlicer(
132
+ nside=self.nside,
133
+ verbose=False,
134
+ lon_col="ra",
135
+ lat_col="dec",
136
+ )
137
+ self.assertEqual(self.testslicer, testslicer2)
138
+ assert (self.testslicer != testslicer2) is False
139
+ testslicer2 = HealpixSlicer(
140
+ nside=self.nside / 2.0,
141
+ verbose=False,
142
+ lon_col="ra",
143
+ lat_col="dec",
144
+ )
145
+ self.assertNotEqual(self.testslicer, testslicer2)
146
+ assert (self.testslicer != testslicer2) is True
147
+
148
+
149
+ class TestHealpixSlicerIteration(unittest.TestCase):
150
+ def setUp(self):
151
+ self.nside = 8
152
+ self.testslicer = HealpixSlicer(
153
+ nside=self.nside,
154
+ verbose=False,
155
+ lon_col="ra",
156
+ lat_col="dec",
157
+ )
158
+ nvalues = 10000
159
+ self.dv = make_data_values(
160
+ size=nvalues,
161
+ minval=0.0,
162
+ maxval=1.0,
163
+ ramin=0,
164
+ ramax=2 * np.pi,
165
+ decmin=-np.pi,
166
+ decmax=0,
167
+ random=33,
168
+ )
169
+ self.testslicer.setup_slicer(self.dv)
170
+
171
+ def tearDown(self):
172
+ del self.testslicer
173
+ self.testslicer = None
174
+
175
+ def test_iteration(self):
176
+ """Test iteration goes through expected range and ra/dec
177
+ are in expected range (radians)."""
178
+ npix = hp.nside2npix(self.nside)
179
+ for i, s in enumerate(self.testslicer):
180
+ self.assertEqual(i, s["slice_point"]["sid"])
181
+ ra = s["slice_point"]["ra"]
182
+ dec = s["slice_point"]["dec"]
183
+ self.assertGreaterEqual(ra, 0)
184
+ self.assertLessEqual(ra, 2 * np.pi)
185
+ self.assertGreaterEqual(dec, -np.pi)
186
+ self.assertLessEqual(dec, np.pi)
187
+ # npix would count starting at 1, while i counts starting at 0 ..
188
+ # so add one to check end point
189
+ self.assertEqual(i + 1, npix)
190
+
191
+ def test_get_item(self):
192
+ """Test getting indexed value."""
193
+ for i, s in enumerate(self.testslicer):
194
+ np.testing.assert_equal(self.testslicer[i], s)
195
+
196
+
197
+ class TestHealpixSlicerSlicing(unittest.TestCase):
198
+ # Note that this is really testing baseSpatialSlicer,
199
+ # as slicing is done there for healpix grid
200
+
201
+ def setUp(self):
202
+ self.nside = 8
203
+ self.radius = 1.8
204
+ self.testslicer = HealpixSlicer(
205
+ nside=self.nside,
206
+ verbose=False,
207
+ lon_col="ra",
208
+ lat_col="dec",
209
+ lat_lon_deg=False,
210
+ radius=self.radius,
211
+ use_camera=False,
212
+ )
213
+ nvalues = 10000
214
+ self.dv = make_data_values(
215
+ size=nvalues,
216
+ minval=0.0,
217
+ maxval=1.0,
218
+ ramin=0,
219
+ ramax=2 * np.pi,
220
+ decmin=-np.pi,
221
+ decmax=0,
222
+ random=44,
223
+ )
224
+
225
+ def tearDown(self):
226
+ del self.testslicer
227
+ self.testslicer = None
228
+
229
+ def test_slicing(self):
230
+ """Test slicing returns (all) data points which are within
231
+ 'radius' of bin point."""
232
+ # Test that slicing fails before setup_slicer
233
+ self.assertRaises(NotImplementedError, self.testslicer._slice_sim_data, 0)
234
+ # Set up and test actual slicing.
235
+ self.testslicer.setup_slicer(self.dv)
236
+ for s in self.testslicer:
237
+ ra = s["slice_point"]["ra"]
238
+ dec = s["slice_point"]["dec"]
239
+ distances = calc_dist_vincenty(ra, dec, self.dv["ra"], self.dv["dec"])
240
+ didxs = np.where(distances <= np.radians(self.radius))
241
+ sidxs = s["idxs"]
242
+ self.assertEqual(len(sidxs), len(didxs[0]))
243
+ if len(sidxs) > 0:
244
+ didxs = np.sort(didxs[0])
245
+ sidxs = np.sort(sidxs)
246
+ np.testing.assert_equal(self.dv["testdata"][didxs], self.dv["testdata"][sidxs])
247
+
248
+
249
+ class TestHealpixChipGap(unittest.TestCase):
250
+ # Note that this is really testing baseSpatialSlicer,
251
+ # as slicing is done there for healpix grid
252
+
253
+ def setUp(self):
254
+ self.nside = 8
255
+ self.radius = 2.041
256
+ self.testslicer = HealpixSlicer(
257
+ nside=self.nside,
258
+ verbose=False,
259
+ lon_col="ra",
260
+ lat_col="dec",
261
+ lat_lon_deg=False,
262
+ radius=self.radius,
263
+ use_camera=True,
264
+ )
265
+ nvalues = 1000
266
+ self.dv = make_data_values(
267
+ size=nvalues,
268
+ minval=0.0,
269
+ maxval=1.0,
270
+ ramin=0,
271
+ ramax=2 * np.pi,
272
+ decmin=-np.pi,
273
+ decmax=0,
274
+ random=55,
275
+ )
276
+
277
+ def tearDown(self):
278
+ del self.testslicer
279
+ self.testslicer = None
280
+
281
+ def test_slicing(self):
282
+ """Test slicing returns (most) data points which are
283
+ within 'radius' of bin point."""
284
+ # Test that slicing fails before setup_slicer
285
+ self.assertRaises(NotImplementedError, self.testslicer._slice_sim_data, 0)
286
+ # Set up and test actual slicing.
287
+ self.testslicer.setup_slicer(self.dv)
288
+ for s in self.testslicer:
289
+ ra = s["slice_point"]["ra"]
290
+ dec = s["slice_point"]["dec"]
291
+ # Find the points of 'dv' which are within self.radius of
292
+ # this slice_point
293
+ distances = calc_dist_vincenty(ra, dec, self.dv["ra"], self.dv["dec"])
294
+ didxs = np.where(distances <= np.radians(self.radius))
295
+ # find the indexes of dv which the slicer says are in the
296
+ # camera footprint
297
+ sidxs = s["idxs"]
298
+ self.assertLessEqual(len(sidxs), len(didxs[0]))
299
+ if len(sidxs) > 0:
300
+ for indx in sidxs:
301
+ self.assertIn(self.dv["testdata"][indx], self.dv["testdata"][didxs])
302
+
303
+
304
+ class TestHealpixCameraRadius(unittest.TestCase):
305
+ # Check that setting the camera radius to a smaller value
306
+ # reduces the number of points matched (that we are using
307
+ # LsstCameraFootprint correctly)
308
+
309
+ def setUp(self):
310
+ self.nside = 8
311
+ self.radius = 2.041
312
+ self.testslicer = HealpixSlicer(
313
+ nside=self.nside,
314
+ verbose=False,
315
+ lon_col="ra",
316
+ lat_col="dec",
317
+ lat_lon_deg=False,
318
+ radius=self.radius,
319
+ use_camera=True,
320
+ )
321
+ self.camera_radius = 0.5
322
+ self.testsmallslicer = HealpixSlicer(
323
+ nside=self.nside,
324
+ verbose=False,
325
+ lon_col="ra",
326
+ lat_col="dec",
327
+ lat_lon_deg=False,
328
+ radius=self.radius,
329
+ use_camera=True,
330
+ camera_radius=self.camera_radius,
331
+ )
332
+ nvalues = 100
333
+ self.dv = make_data_values(
334
+ size=nvalues * hp.nside2npix(self.nside),
335
+ minval=0.0,
336
+ maxval=1.0,
337
+ ramin=0,
338
+ ramax=2 * np.pi,
339
+ decmin=-np.pi,
340
+ decmax=0,
341
+ random=55,
342
+ )
343
+ # Replace ra/dec to make them close to healpix points
344
+ hpix = np.arange(0, hp.nside2npix(self.nside))
345
+ ra, dec = hp.pix2ang(nside=self.nside, ipix=hpix, lonlat=True)
346
+ rng = np.random.RandomState(1147)
347
+ rr = rng.rand(nvalues) * 1.5
348
+ ra = (ra[:, np.newaxis] + rr).reshape(len(ra) * len(rr))
349
+ dec = (dec[:, np.newaxis] + rr).reshape(len(dec) * len(rr))
350
+ self.dv["ra"] = np.radians(ra)
351
+ self.dv["dec"] = np.radians(dec)
352
+
353
+ def tearDown(self):
354
+ del self.testslicer
355
+ self.testslicer = None
356
+ del self.testsmallslicer
357
+ self.testsmallslicer = None
358
+
359
+ def test_slicing(self):
360
+ """Test slicing returns (most) data points which are
361
+ within 'radius' of bin point or camera_radius for small slicer"""
362
+ # Test that slicing fails before setup_slicer
363
+ self.assertRaises(NotImplementedError, self.testslicer._slice_sim_data, 0)
364
+ # Set up and test actual slicing.
365
+ self.testslicer.setup_slicer(self.dv)
366
+ self.testsmallslicer.setup_slicer(self.dv)
367
+ for s, ss in zip(self.testslicer, self.testsmallslicer):
368
+ ra = s["slice_point"]["ra"]
369
+ dec = s["slice_point"]["dec"]
370
+ # Find the points of 'dv' which are within self.radius of
371
+ # this slice_point
372
+ distances = calc_dist_vincenty(ra, dec, self.dv["ra"], self.dv["dec"])
373
+ didxs = np.where(distances <= np.radians(self.radius))
374
+ # find the indexes of dv which the slicer says are in the
375
+ # camera footprint
376
+ sidxs = s["idxs"]
377
+ self.assertLessEqual(len(sidxs), len(didxs[0]))
378
+ if len(sidxs) > 0:
379
+ for indx in sidxs:
380
+ self.assertIn(self.dv["testdata"][indx], self.dv["testdata"][didxs])
381
+ # find the indexes of dv which the slicer says are in the
382
+ # camera footprint
383
+ sidxs = ss["idxs"]
384
+ self.assertLessEqual(len(sidxs), len(didxs[0]))
385
+ if len(sidxs) > 0:
386
+ for indx in sidxs:
387
+ self.assertIn(self.dv["testdata"][indx], self.dv["testdata"][didxs])
388
+ self.assertLess(len(ss["idxs"]), len(s["idxs"]))
389
+
390
+
391
+ class TestHealpixSlicerPlotting(unittest.TestCase):
392
+ def setUp(self):
393
+ rng = np.random.RandomState(713244122)
394
+ self.nside = 16
395
+ self.radius = 1.8
396
+ self.testslicer = HealpixSlicer(
397
+ nside=self.nside,
398
+ verbose=False,
399
+ lat_lon_deg=False,
400
+ lon_col="ra",
401
+ lat_col="dec",
402
+ radius=self.radius,
403
+ )
404
+ nvalues = 10000
405
+ self.dv = make_data_values(
406
+ size=nvalues,
407
+ minval=0.0,
408
+ maxval=1.0,
409
+ ramin=0,
410
+ ramax=2 * np.pi,
411
+ decmin=-np.pi,
412
+ decmax=0,
413
+ random=66,
414
+ )
415
+ self.testslicer.setup_slicer(self.dv)
416
+ self.metricdata = ma.MaskedArray(
417
+ data=np.zeros(len(self.testslicer), dtype="float"),
418
+ mask=np.zeros(len(self.testslicer), "bool"),
419
+ fill_value=self.testslicer.badval,
420
+ )
421
+ for i, b in enumerate(self.testslicer):
422
+ idxs = b["idxs"]
423
+ if len(idxs) > 0:
424
+ self.metricdata.data[i] = np.mean(self.dv["testdata"][idxs])
425
+ else:
426
+ self.metricdata.mask[i] = True
427
+ self.metricdata2 = ma.MaskedArray(
428
+ data=rng.rand(len(self.testslicer)),
429
+ mask=np.zeros(len(self.testslicer), "bool"),
430
+ fill_value=self.testslicer.badval,
431
+ )
432
+
433
+ def tearDown(self):
434
+ del self.testslicer
435
+ self.testslicer = None
436
+
437
+
438
+ if __name__ == "__main__":
439
+ unittest.main()
@@ -0,0 +1,273 @@
1
+ import unittest
2
+
3
+ import healpy as hp
4
+ import numpy as np
5
+ import numpy.lib.recfunctions as rfn
6
+
7
+ from rubin_sim.maf.slicers import HealpixSubsetSlicer
8
+
9
+
10
+ def make_data_values(
11
+ size=100,
12
+ minval=0.0,
13
+ maxval=1.0,
14
+ ramin=0,
15
+ ramax=2 * np.pi,
16
+ decmin=-np.pi,
17
+ decmax=np.pi,
18
+ random=1172,
19
+ ):
20
+ """Generate a simple array of numbers, evenly arranged between min/max,
21
+ in 1 dimensions (optionally sorted), together with RA/Dec values
22
+ for each data value."""
23
+ data = []
24
+ # Generate data values min - max.
25
+ datavalues = np.arange(0, size, dtype="float")
26
+ datavalues *= (float(maxval) - float(minval)) / (datavalues.max() - datavalues.min())
27
+ datavalues += minval
28
+ rng = np.random.RandomState(random)
29
+ randorder = rng.rand(size)
30
+ randind = np.argsort(randorder)
31
+ datavalues = datavalues[randind]
32
+ datavalues = np.array(list(zip(datavalues)), dtype=[("testdata", "float")])
33
+ data.append(datavalues)
34
+ # Generate RA/Dec values equally spaces on sphere between ramin/max,
35
+ # decmin/max.
36
+ ra = np.arange(0, size, dtype="float")
37
+ ra *= (float(ramax) - float(ramin)) / (ra.max() - ra.min())
38
+ randorder = rng.rand(size)
39
+ randind = np.argsort(randorder)
40
+ ra = ra[randind]
41
+ ra = np.array(list(zip(ra)), dtype=[("ra", "float")])
42
+ data.append(ra)
43
+ v = np.arange(0, size, dtype="float")
44
+ v *= ((np.cos(decmax + np.pi) + 1.0) / 2.0 - (np.cos(decmin + np.pi) + 1.0) / 2.0) / (v.max() - v.min())
45
+ v += (np.cos(decmin + np.pi) + 1.0) / 2.0
46
+ dec = np.arccos(2 * v - 1) - np.pi
47
+ randorder = rng.rand(size)
48
+ randind = np.argsort(randorder)
49
+ dec = dec[randind]
50
+ dec = np.array(list(zip(dec)), dtype=[("dec", "float")])
51
+ data.append(dec)
52
+ # Add in rotation angle
53
+ rot = rng.rand(len(dec)) * 2 * np.pi
54
+ data.append(np.array(rot, dtype=[("rotSkyPos", "float")]))
55
+ mjd = np.arange(len(dec)) * 0.1
56
+ data.append(np.array(mjd, dtype=[("observationStartMJD", "float")]))
57
+ data = rfn.merge_arrays(data, flatten=True, usemask=False)
58
+ return data
59
+
60
+
61
+ def calc_dist_vincenty(ra1, dec1, ra2, dec2):
62
+ """Calculates distance on a sphere using the Vincenty formula.
63
+ Give this function RA/Dec values in radians.
64
+ Returns angular distance(s), in radians.
65
+ Note that since this is all numpy, you could input arrays of RA/Decs.
66
+ """
67
+ d1 = (np.cos(dec2) * np.sin(ra2 - ra1)) ** 2 + (
68
+ np.cos(dec1) * np.sin(dec2) - np.sin(dec1) * np.cos(dec2) * np.cos(ra2 - ra1)
69
+ ) ** 2
70
+ d1 = np.sqrt(d1)
71
+ d2 = np.sin(dec1) * np.sin(dec2) + np.cos(dec1) * np.cos(dec2) * np.cos(ra2 - ra1)
72
+ D = np.arctan2(d1, d2)
73
+ return D
74
+
75
+
76
+ class TestHealpixSubsetSlicerSetup(unittest.TestCase):
77
+ def setUp(self):
78
+ self.nside = 16
79
+ idxs = np.arange(0, hp.nside2npix(self.nside))
80
+ self.idxs = idxs[np.where(idxs < idxs.max() / 2)]
81
+
82
+ def test_slicertype(self):
83
+ """Test instantiation of slicer sets slicer type as expected."""
84
+ testslicer = HealpixSubsetSlicer(
85
+ nside=self.nside,
86
+ hpid=self.idxs,
87
+ verbose=False,
88
+ )
89
+ self.assertEqual(testslicer.slicer_name, testslicer.__class__.__name__)
90
+ self.assertEqual(testslicer.slicer_name, "HealpixSubsetSlicer")
91
+
92
+
93
+ class TestHealpixSlicerEqual(unittest.TestCase):
94
+ def setUp(self):
95
+ self.nside = 16
96
+ self.testslicer = HealpixSubsetSlicer(
97
+ nside=self.nside,
98
+ hpid=np.arange(0, 10),
99
+ verbose=False,
100
+ lon_col="ra",
101
+ lat_col="dec",
102
+ )
103
+ nvalues = 10000
104
+ self.dv = make_data_values(
105
+ size=nvalues,
106
+ minval=0.0,
107
+ maxval=1.0,
108
+ ramin=0,
109
+ ramax=2 * np.pi,
110
+ decmin=-np.pi,
111
+ decmax=0,
112
+ random=22,
113
+ )
114
+ self.testslicer.setup_slicer(self.dv)
115
+
116
+ def tearDown(self):
117
+ del self.testslicer
118
+ del self.dv
119
+ self.testslicer = None
120
+
121
+ def test_slicer_equivalence(self):
122
+ """Test that slicers are marked equal when appropriate,
123
+ and unequal when appropriate.
124
+ """
125
+ # Note that they are judged equal based on nsides
126
+ # (not on data in ra/dec spatial tree).
127
+ testslicer2 = HealpixSubsetSlicer(
128
+ nside=self.nside,
129
+ hpid=np.arange(0, 10),
130
+ verbose=False,
131
+ lon_col="ra",
132
+ lat_col="dec",
133
+ )
134
+ self.assertEqual(self.testslicer, testslicer2)
135
+ assert (self.testslicer != testslicer2) is False
136
+ testslicer2 = HealpixSubsetSlicer(
137
+ nside=self.nside,
138
+ hpid=np.arange(10, 20),
139
+ verbose=False,
140
+ lon_col="ra",
141
+ lat_col="dec",
142
+ )
143
+ self.assertNotEqual(self.testslicer, testslicer2)
144
+ assert (self.testslicer != testslicer2) is True
145
+
146
+
147
+ class TestHealpixSlicerIteration(unittest.TestCase):
148
+ def setUp(self):
149
+ self.nside = 8
150
+ self.hpid = np.arange(10, 20)
151
+ self.testslicer = HealpixSubsetSlicer(
152
+ nside=self.nside,
153
+ hpid=self.hpid,
154
+ verbose=False,
155
+ lon_col="ra",
156
+ lat_col="dec",
157
+ )
158
+ nvalues = 10000
159
+ self.dv = make_data_values(
160
+ size=nvalues,
161
+ minval=0.0,
162
+ maxval=1.0,
163
+ ramin=0,
164
+ ramax=2 * np.pi,
165
+ decmin=-np.pi,
166
+ decmax=0,
167
+ random=33,
168
+ )
169
+ self.testslicer.setup_slicer(self.dv)
170
+
171
+ def tearDown(self):
172
+ del self.testslicer
173
+ self.testslicer = None
174
+
175
+ def test_iteration(self):
176
+ """Test iteration goes through expected range and ra/dec
177
+ are in expected range (radians).
178
+ """
179
+ for i, s in enumerate(self.testslicer):
180
+ # We do not expect testslicer.slice_point['sid'] to == i ..
181
+ # The slicer will only iterate over the subset
182
+ self.assertEqual(self.hpid[i], s["slice_point"]["sid"])
183
+ ra = s["slice_point"]["ra"]
184
+ dec = s["slice_point"]["dec"]
185
+ self.assertGreaterEqual(ra, 0)
186
+ self.assertLessEqual(ra, 2 * np.pi)
187
+ self.assertGreaterEqual(dec, -np.pi)
188
+ self.assertLessEqual(dec, np.pi)
189
+ self.assertEqual(i + 1, len(self.hpid))
190
+
191
+ def test_get_item(self):
192
+ """Test getting indexed value."""
193
+ for i, s in enumerate(self.testslicer):
194
+ np.testing.assert_equal(self.testslicer[self.hpid[i]], s)
195
+
196
+
197
+ class TestHealpixSlicerSlicing(unittest.TestCase):
198
+ # Note that this is really testing baseSpatialSlicer,
199
+ # as slicing is done there for healpix grid
200
+
201
+ def setUp(self):
202
+ self.nside = 8
203
+ self.radius = 1.8
204
+ self.testslicer = HealpixSubsetSlicer(
205
+ nside=self.nside,
206
+ hpid=np.arange(0, hp.nside2npix(self.nside)),
207
+ verbose=False,
208
+ lon_col="ra",
209
+ lat_col="dec",
210
+ lat_lon_deg=False,
211
+ radius=self.radius,
212
+ use_camera=False,
213
+ )
214
+ nvalues = 10000
215
+ self.dv = make_data_values(
216
+ size=nvalues,
217
+ minval=0.0,
218
+ maxval=1.0,
219
+ ramin=0,
220
+ ramax=2 * np.pi,
221
+ decmin=-np.pi,
222
+ decmax=0,
223
+ random=44,
224
+ )
225
+
226
+ def tearDown(self):
227
+ del self.testslicer
228
+ self.testslicer = None
229
+
230
+ def test_slicing(self):
231
+ """Test slicing returns (all) data points which are within
232
+ 'radius' of bin point."""
233
+ # Test that slicing fails before setup_slicer
234
+ self.assertRaises(NotImplementedError, self.testslicer._slice_sim_data, 0)
235
+ # Set up and test actual slicing.
236
+ self.testslicer.setup_slicer(self.dv)
237
+ for s in self.testslicer:
238
+ ra = s["slice_point"]["ra"]
239
+ dec = s["slice_point"]["dec"]
240
+ distances = calc_dist_vincenty(ra, dec, self.dv["ra"], self.dv["dec"])
241
+ didxs = np.where(distances <= np.radians(self.radius))
242
+ sidxs = s["idxs"]
243
+ self.assertEqual(len(sidxs), len(didxs[0]))
244
+ if len(sidxs) > 0:
245
+ didxs = np.sort(didxs[0])
246
+ sidxs = np.sort(sidxs)
247
+ np.testing.assert_equal(self.dv["testdata"][didxs], self.dv["testdata"][sidxs])
248
+
249
+ def test_subset_slice(self):
250
+ testslicer = HealpixSubsetSlicer(
251
+ nside=self.nside,
252
+ hpid=np.arange(0, 2),
253
+ verbose=False,
254
+ lon_col="ra",
255
+ lat_col="dec",
256
+ lat_lon_deg=False,
257
+ radius=self.radius,
258
+ use_camera=False,
259
+ )
260
+ testslicer.setup_slicer(self.dv)
261
+ self.testslicer.setup_slicer(self.dv)
262
+ # For points which return values when used with the full set
263
+ # of points (self.testslicer)
264
+ # there will be no data when used with the subset of points
265
+ for s in self.testslicer:
266
+ if s["slice_point"]["sid"] > 2:
267
+ if len(s["idxs"]) > 0:
268
+ islice = s["slice_point"]["sid"]
269
+ self.assertTrue(len(testslicer[islice]["idxs"]) == 0)
270
+
271
+
272
+ if __name__ == "__main__":
273
+ unittest.main()