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,486 @@
1
+ __all__ = (
2
+ "BaseMoStacker",
3
+ "MoMagStacker",
4
+ "AppMagStacker",
5
+ "CometAppMagStacker",
6
+ "SNRStacker",
7
+ "EclStacker",
8
+ )
9
+
10
+ import warnings
11
+
12
+ import numpy as np
13
+
14
+ from .base_stacker import BaseStacker
15
+ from .mo_phase import phase__halley_marcus
16
+
17
+ # Willmer 2018, ApJS 236, 47
18
+ # VEGA V mag and AB mag of sun (LSST-equivalent bandpasses)
19
+ VMAG_SUN = -26.76 # Vega mag
20
+ AB_SUN = {"u": -25.30, "g": -26.52, "r": -26.93, "i": -27.05, "z": -27.07, "y": -27.07}
21
+ KM_PER_AU = 149597870.7
22
+
23
+
24
+ class BaseMoStacker(BaseStacker):
25
+ """Base class for moving object (SSobject) stackers.
26
+ Relevant for MoSlicer ssObs (pd.dataframe).
27
+
28
+ Provided to add moving-object specific API for 'run'
29
+ method of moving object stackers.
30
+ """
31
+
32
+ def run(self, sso_obs, href, hval=None):
33
+ # Redefine this here, as the API does not match BaseStacker.
34
+ if hval is None:
35
+ hval = href
36
+ if len(sso_obs) == 0:
37
+ return sso_obs
38
+ # Add the columns.
39
+ with warnings.catch_warnings():
40
+ warnings.simplefilter("ignore")
41
+ sso_obs, cols_present = self._add_stacker_cols(sso_obs)
42
+ # Here we don't really care about cols_present, because almost
43
+ # every time we will be readding
44
+ # columns anymore (for different H values).
45
+ return self._run(sso_obs, href, hval)
46
+
47
+
48
+ class MoMagStacker(BaseMoStacker):
49
+ """Add columns relevant to SSobject apparent magnitudes and
50
+ visibility to the slicer ssoObs
51
+ dataframe, given a particular Href and current h_val.
52
+
53
+ Specifically, this stacker adds magLimit, appMag, SNR, and vis.
54
+ magLimit indicates the appropriate limiting magnitude to consider
55
+ for a particular object in a particular
56
+ observation, when combined with the losses due to detection
57
+ (dmag_detect) or trailing (dmagTrail).
58
+ appMag adds the apparent magnitude in the filter of the current object,
59
+ at the current h_val.
60
+ SNR adds the SNR of this object, given the magLimit.
61
+ vis adds a flag (0/1) indicating whether an object was visible
62
+ (assuming a 5sigma threshhold including
63
+ some probabilistic determination of visibility).
64
+
65
+ Parameters
66
+ ----------
67
+ m5Col : `str`, optional
68
+ Name of the column describing the 5 sigma depth of each visit.
69
+ Default fiveSigmaDepth.
70
+ lossCol : `str`, optional
71
+ Name of the column describing the magnitude losses,
72
+ due to trailing (dmagTrail) or detection (dmag_detect).
73
+ Default dmag_detect.
74
+ gamma : `float`, optional
75
+ The 'gamma' value for calculating SNR. Default 0.038.
76
+ LSST range under normal conditions is about 0.037 to 0.039.
77
+ sigma : `float`, optional
78
+ The 'sigma' value for probabilistic prediction of whether or not
79
+ an object is visible at 5sigma.
80
+ Default 0.12.
81
+ The probabilistic prediction of visibility is based on
82
+ Fermi-Dirac completeness formula (see SDSS, eqn 24, Stripe82 analysis:
83
+ http://iopscience.iop.org/0004-637X/794/2/120/pdf/apj_794_2_120.pdf).
84
+ randomSeed: `int` or None, optional
85
+ If set, then used as the random seed for the numpy random number
86
+ generation for the dither offsets.
87
+ Default: None.
88
+ """
89
+
90
+ cols_added = ["appMag", "SNR", "vis"]
91
+
92
+ def __init__(
93
+ self,
94
+ magtype="asteroid",
95
+ v_mag_col="magV",
96
+ color_col="dmag_color",
97
+ loss_col="dmag_detect",
98
+ m5_col="fiveSigmaDepth",
99
+ seeing_col="seeingFwhmGeom",
100
+ filter_col="band",
101
+ gamma=0.038,
102
+ sigma=0.12,
103
+ random_seed=None,
104
+ ):
105
+ if magtype == "asteroid":
106
+ self.mag_stacker = AppMagStacker(v_mag_col=v_mag_col, color_col=color_col, loss_col=loss_col)
107
+ self.cols_req = [m5_col, v_mag_col, color_col, loss_col]
108
+ elif magtype.startswith("comet"):
109
+ # magtype should be = comet_oort comet_short or comet_mbc
110
+ comet_type = magtype.split("_")[-1]
111
+ self.mag_stacker = CometAppMagStacker(
112
+ comet_type=comet_type,
113
+ ap=0.04,
114
+ rh_col="helio_dist",
115
+ delta_col="geo_dist",
116
+ phase_col="phase",
117
+ seeing_col=seeing_col,
118
+ ap_scale=1,
119
+ filter_col=filter_col,
120
+ v_mag_col=v_mag_col,
121
+ color_col=color_col,
122
+ loss_col=loss_col,
123
+ )
124
+ self.cols_req = [
125
+ m5_col,
126
+ v_mag_col,
127
+ color_col,
128
+ loss_col,
129
+ "helio_dist",
130
+ "geo_dist",
131
+ "phase",
132
+ seeing_col,
133
+ filter_col,
134
+ ]
135
+ else:
136
+ self.mag_stacker = AppMagNullStacker()
137
+ self.snr_stacker = SNRStacker(
138
+ app_mag_col="appMag",
139
+ m5_col=m5_col,
140
+ gamma=gamma,
141
+ sigma=sigma,
142
+ random_seed=random_seed,
143
+ )
144
+
145
+ self.units = ["mag", "mag", "SNR", ""]
146
+
147
+ def _run(self, sso_obs, href, hval):
148
+ # hval = current H value (useful if cloning over H range),
149
+ # href = reference H value from orbit.
150
+ # Without cloning, href = hval.
151
+ # add apparent magnitude
152
+ self.mag_stacker._run(sso_obs, href, hval)
153
+ # add snr
154
+ self.snr_stacker._run(sso_obs, href, hval)
155
+ return sso_obs
156
+
157
+
158
+ class AppMagNullStacker(BaseMoStacker):
159
+ """Do nothing to calculate an apparent magnitude.
160
+
161
+ This assumes an apparent magnitude was part of the input data and
162
+ does not need to be modified (no
163
+ cloning, color terms, trailing losses, etc). Just return the appMag column.
164
+
165
+ This would not be necessary in general, but appMag is treated as a
166
+ special column (because we must have an
167
+ apparent magnitude for most of the basic moving object metrics,
168
+ and it must be calculated before SNR
169
+ if that is also needed).
170
+ """
171
+
172
+ cols_added = ["appMag"]
173
+
174
+ def __init__(self, app_mag_col="appMag"):
175
+ self.app_mag_col = app_mag_col
176
+ self.units = [
177
+ "mag",
178
+ ]
179
+ self.cols_req = [self.app_mag_col]
180
+
181
+ def _run(self, sso_obs, href, hval):
182
+ sso_obs["appMag"] = sso_obs[self.app_mag_col]
183
+ return sso_obs
184
+
185
+
186
+ class AppMagStacker(BaseMoStacker):
187
+ """Add apparent magnitude of an object for the current h_val
188
+ (compared to Href in the orbit file),
189
+ incorporating the magnitude losses due to trailing/detection,
190
+ as well as the color of the object.
191
+
192
+ This is calculated from the reported mag_v in the input observation
193
+ file (calculated assuming Href) as:
194
+ .. codeblock::python
195
+
196
+ ssoObs['appMag'] = ssoObs[self.vMagCol] + ssoObs[self.colorCol] +
197
+ ssoObs[self.lossCol] + h_val - Href
198
+
199
+ Using the vMag reported in the input observations implicitly uses
200
+ the phase curve coded in at that point;
201
+ for Oorb this is an H/G phase curve, with G=0.15 unless otherwise
202
+ specified in the orbit file.
203
+ See sims_movingObjects for more details on the color and loss quantities.
204
+
205
+ Parameters
206
+ ----------
207
+ v_mag_col : `str`, optional
208
+ Name of the column containing the base V magnitude for the
209
+ object at H=Href.
210
+ loss_col : `str`, optional
211
+ Name of the column describing the magnitude losses,
212
+ due to trailing (dmagTrail) or detection (dmag_detect).
213
+ Default dmag_detect.
214
+ color_col : `str`, optional
215
+ Name of the column describing the color correction
216
+ (into the observation filter, from V).
217
+ Default dmag_color.
218
+ """
219
+
220
+ cols_added = ["appMag"]
221
+
222
+ def __init__(self, v_mag_col="magV", color_col="dmag_color", loss_col="dmag_detect"):
223
+ self.v_mag_col = v_mag_col
224
+ self.color_col = color_col
225
+ self.loss_col = loss_col
226
+ self.cols_req = [self.v_mag_col, self.color_col, self.loss_col]
227
+ self.units = [
228
+ "mag",
229
+ ]
230
+
231
+ def _run(self, sso_obs, href, hval):
232
+ # hval = current H value (useful if cloning over H range),
233
+ # href = reference H value from orbit.
234
+ # Without cloning, href = hval.
235
+ sso_obs["appMag"] = (
236
+ sso_obs[self.v_mag_col] + sso_obs[self.color_col] + sso_obs[self.loss_col] + hval - href
237
+ )
238
+ return sso_obs
239
+
240
+
241
+ class CometAppMagStacker(BaseMoStacker):
242
+ """Add a cometary apparent magnitude, including nucleus and coma,
243
+ based on a calculation of
244
+ Afrho (using the current h_val) and a Halley-Marcus phase curve
245
+ for the coma brightness.
246
+
247
+ Parameters
248
+ ----------
249
+ cometType : `str`, optional
250
+ Type of comet - short, oort, or mbc.
251
+ This setting also sets the value of Afrho1 and k:
252
+ short = Afrho1 / R^2 = 100 cm/km2, k = -4
253
+ oort = Afrho1 / R^2 = 1000 cm/km2, k = -2
254
+ mbc = Afrho1 / R^2 = 4000 cm/km2, k = -6.
255
+ Default = 'oort'.
256
+ It is also possible to pass this a dictionary instead:
257
+ the dictionary should contain 'k' and
258
+ 'afrho1_const' keys, which will be used to set these values directly.
259
+ (e.g. cometType = {'k': -3.5, 'afrho1_const': 1500}).
260
+ ap : `float`, optional
261
+ The albedo for calculating the object's size. Default 0.04
262
+ rh_col : `str`, optional
263
+ The column name for the heliocentric distance (in AU).
264
+ Default 'helio_dist'.
265
+ delta_col : `str`, optional
266
+ The column name for the geocentric distance (in AU).
267
+ Default 'geo_dist'.
268
+ phase_col : `str`, optional
269
+ The column name for the phase value (in degrees).
270
+ Default 'phase'.
271
+ """
272
+
273
+ cols_added = ["appMag"]
274
+
275
+ def __init__(
276
+ self,
277
+ comet_type="oort",
278
+ ap=0.04,
279
+ rh_col="helio_dist",
280
+ delta_col="geo_dist",
281
+ phase_col="phase",
282
+ seeing_col="FWHMgeom",
283
+ ap_scale=1,
284
+ filter_col="band",
285
+ v_mag_col="magV",
286
+ color_col="dmag_color",
287
+ loss_col="dmag_detect",
288
+ ):
289
+ self.units = ["mag"] # new column units
290
+ # Set up k and Afrho1 constant values.
291
+ comet_types = {
292
+ "short": {"k": -4, "Afrho1_const": 100},
293
+ "oort": {"k": -2, "Afrho1_const": 1000},
294
+ "mbc": {"k": -6, "Afrho1_const": 4000},
295
+ }
296
+ self.k = None
297
+ self.afrho1_const = None
298
+ if isinstance(comet_type, str):
299
+ if comet_type in comet_types:
300
+ self.k = comet_types[comet_type]["k"]
301
+ self.afrho1_const = comet_types[comet_type]["Afrho1_const"]
302
+ if isinstance(comet_type, dict):
303
+ if "k" in comet_type:
304
+ self.k = comet_type["k"]
305
+ if "Afrho1_const" in comet_type:
306
+ self.afrho1_const = comet_type["Afrho1_const"]
307
+ if self.k is None or self.afrho1_const is None:
308
+ raise ValueError(
309
+ f"comet_type must be a string {comet_types} or "
310
+ f'dict containing "k" and "Afrho1_const" - but received {comet_type}'
311
+ )
312
+ # Phew, now set the simple stuff.
313
+ self.ap = ap
314
+ self.rh_col = rh_col
315
+ self.delta_col = delta_col
316
+ self.phase_col = phase_col
317
+ self.seeing_col = seeing_col
318
+ self.ap_scale = ap_scale
319
+ self.filter_col = filter_col
320
+ self.v_mag_col = v_mag_col
321
+ self.color_col = color_col
322
+ self.loss_col = loss_col
323
+ # names of required columns
324
+ self.cols_req = [
325
+ self.rh_col,
326
+ self.delta_col,
327
+ self.phase_col,
328
+ self.seeing_col,
329
+ self.filter_col,
330
+ self.v_mag_col,
331
+ self.color_col,
332
+ self.loss_col,
333
+ ]
334
+
335
+ def _run(self, sso_obs, href, hval):
336
+ # Calculate radius from the current H value (hval).
337
+ radius = 10 ** (0.2 * (VMAG_SUN - hval)) / np.sqrt(self.ap) * KM_PER_AU
338
+ # Calculate expected Afrho - this is a value that describes
339
+ # how the brightness of the coma changes
340
+ afrho1 = self.afrho1_const * radius**2
341
+ phase_val = phase__halley_marcus(sso_obs[self.phase_col])
342
+ # afrho is equivalent to a sort of 'absolute' magnitude of the coma
343
+ afrho = afrho1 * sso_obs[self.rh_col] ** self.k * phase_val
344
+ # rho describes the projected area on the sky
345
+ # (project the aperture into cm on-sky)
346
+ # Using the seeing * apScale as the aperture
347
+ radius_aperture = sso_obs[self.seeing_col] * self.ap_scale
348
+ rho = 725e5 * sso_obs[self.delta_col] * radius_aperture
349
+ # Calculate the expected apparent of the comet coma = sun + correction
350
+ delta = sso_obs[self.delta_col] * KM_PER_AU * 1000 # delta in cm
351
+ dm = -2.5 * np.log10(afrho * rho / (2 * sso_obs[self.rh_col] * delta) ** 2)
352
+ coma = np.zeros(len(sso_obs), float)
353
+ # This calculates a coma mag that scales with the sun's color in
354
+ # each bandpass, but the coma
355
+ # modification is gray (i.e. it's just reflecting sunlight)
356
+ for f in sso_obs[self.filter_col]:
357
+ match = np.where(sso_obs[self.filter_col] == f)
358
+ coma[match] = AB_SUN[f] + dm[match]
359
+ # Calculate cometary nucleus magnitude -- we'll use the
360
+ # apparent V mag adapted from OOrb as well as
361
+ # the object's color - these are generally assumed to be
362
+ # D type (which was used in sims_movingObjects)
363
+ nucleus = sso_obs[self.v_mag_col] + sso_obs[self.color_col] + sso_obs[self.loss_col] + hval - href
364
+ # add coma and nucleus then ready for calculation of SNR, etc.
365
+ sso_obs["appMag"] = -2.5 * np.log10(10 ** (-0.4 * coma) + 10 ** (-0.4 * nucleus))
366
+ return sso_obs
367
+
368
+
369
+ class SNRStacker(BaseMoStacker):
370
+ """Add SNR and visibility for a particular object,
371
+ given the five sigma depth of the image and the
372
+ apparent magnitude (whether from AppMagStacker or CometAppMagStacker etc).
373
+
374
+ The SNR simply calculates the SNR based on the five sigma depth and
375
+ the apparent magnitude.
376
+ The 'vis' column is a probabilistic flag (0/1) indicating whether
377
+ the object was detected, assuming
378
+ a 5-sigma SNR threshold and then applying a probabilistic cut on whether
379
+ it was detected or not (i.e.
380
+ there is a gentle roll-over in 'vis' from 1 to 0 depending on the
381
+ SNR of the object).
382
+ This is based on the Fermi-Dirac completeness formula as described
383
+ in equation 24 of the Stripe 82 SDSS
384
+ analysis here:
385
+ http://iopscience.iop.org/0004-637X/794/2/120/pdf/apj_794_2_120.pdf.
386
+
387
+ Parameters
388
+ ----------
389
+ app_mag_col : `str`, optional
390
+ Name of the column describing the apparent magnitude of the object.
391
+ Default 'appMag'.
392
+ m5_col : `str`, optional
393
+ Name of the column describing the 5 sigma depth of each visit.
394
+ Default fiveSigmaDepth.
395
+ gamma : `float`, optional
396
+ The 'gamma' value for calculating SNR. Default 0.038.
397
+ LSST range under normal conditions is about 0.037 to 0.039.
398
+ sigma : `float`, optional
399
+ The 'sigma' value for probabilistic prediction of whether or not
400
+ an object is visible at 5sigma.
401
+ Default 0.12.
402
+ The probabilistic prediction of visibility is based on Fermi-Dirac
403
+ completeness formula (see SDSS, eqn 24, Stripe82 analysis:
404
+ http://iopscience.iop.org/0004-637X/794/2/120/pdf/apj_794_2_120.pdf).
405
+ random_seed: `int` or None, optional
406
+ If set, then used as the random seed for the numpy random number
407
+ generation for the probability of detection. Default: None.
408
+ """
409
+
410
+ cols_added = ["SNR", "vis"]
411
+
412
+ def __init__(
413
+ self,
414
+ app_mag_col="appMag",
415
+ m5_col="fiveSigmaDepth",
416
+ gamma=0.038,
417
+ sigma=0.12,
418
+ random_seed=None,
419
+ ):
420
+ self.app_mag_col = app_mag_col
421
+ self.m5_col = m5_col
422
+ self.gamma = gamma
423
+ self.sigma = sigma
424
+ self.random_seed = random_seed
425
+ self.cols_req = [self.app_mag_col, self.m5_col]
426
+ self.units = ["SNR", ""]
427
+
428
+ def _run(self, sso_obs, href, hval):
429
+ # hval = current H value (useful if cloning over H range),
430
+ # href = reference H value from orbit.
431
+ # Without cloning, href = hval.
432
+ xval = np.power(10, 0.5 * (sso_obs[self.app_mag_col] - sso_obs[self.m5_col]))
433
+ sso_obs["SNR"] = 1.0 / np.sqrt((0.04 - self.gamma) * xval + self.gamma * xval * xval)
434
+ completeness = 1.0 / (1 + np.exp((sso_obs[self.app_mag_col] - sso_obs[self.m5_col]) / self.sigma))
435
+ if not hasattr(self, "_rng"):
436
+ if self.random_seed is not None:
437
+ self._rng = np.random.RandomState(self.random_seed)
438
+ else:
439
+ self._rng = np.random.RandomState(734421)
440
+ probability = self._rng.random_sample(len(sso_obs[self.app_mag_col]))
441
+ sso_obs["vis"] = np.where(probability <= completeness, 1, 0)
442
+ return sso_obs
443
+
444
+
445
+ class EclStacker(BaseMoStacker):
446
+ """
447
+ Add ecliptic latitude/longitude (ecLat/ecLon) to the slicer ssoObs
448
+ (in degrees).
449
+
450
+ Parameters
451
+ -----------
452
+ ra_col : `str`, optional
453
+ Name of the RA column to convert to ecliptic lat/long. Default 'ra'.
454
+ dec_col : `str`, optional
455
+ Name of the Dec column to convert to ecliptic lat/long. Default 'dec'.
456
+ in_deg : `bool`, optional
457
+ Flag indicating whether RA/Dec are in degrees. Default True.
458
+ """
459
+
460
+ cols_added = ["ecLat", "ecLon"]
461
+
462
+ def __init__(self, ra_col="ra", dec_col="dec", in_deg=True):
463
+ self.ra_col = ra_col
464
+ self.dec_col = dec_col
465
+ self.in_deg = in_deg
466
+ self.cols_req = [self.ra_col, self.dec_col]
467
+ self.units = ["deg", "deg"]
468
+ self.ecnode = 0.0
469
+ self.ecinc = np.radians(23.439291)
470
+
471
+ def _run(self, sso_obs, href, hval):
472
+ ra = sso_obs[self.ra_col]
473
+ dec = sso_obs[self.dec_col]
474
+ if self.in_deg:
475
+ ra = np.radians(ra)
476
+ dec = np.radians(dec)
477
+ x = np.cos(ra) * np.cos(dec)
478
+ y = np.sin(ra) * np.cos(dec)
479
+ z = np.sin(dec)
480
+ xp = x
481
+ yp = np.cos(self.ecinc) * y + np.sin(self.ecinc) * z
482
+ zp = -np.sin(self.ecinc) * y + np.cos(self.ecinc) * z
483
+ sso_obs["ecLat"] = np.degrees(np.arcsin(zp))
484
+ sso_obs["ecLon"] = np.degrees(np.arctan2(yp, xp))
485
+ sso_obs["ecLon"] = sso_obs["ecLon"] % 360
486
+ return sso_obs
@@ -0,0 +1,187 @@
1
+ __all__ = ("find_telescopes", "NFollowStacker")
2
+
3
+
4
+ import numpy as np
5
+
6
+ from .base_stacker import BaseStacker
7
+ from .coord_stackers import ra_dec2_alt_az
8
+
9
+
10
+ def find_telescopes(min_size=3.0):
11
+ """Finds telescopes larger than min_size,
12
+ from list of large telescopes based on
13
+ http://astro.nineplanets.org/bigeyes.html.
14
+
15
+ Returns
16
+ -------
17
+ np.recarray
18
+ Array of large telescopes with columns [aperture, name, lat, lon].
19
+ """
20
+ # Aperture Name Location http://astro.nineplanets.org/bigeyes.html
21
+ telescopes = [
22
+ [10.4, "Gran Canarias", "La Palma"],
23
+ [10.0, "Keck", "Mauna Kea"],
24
+ [10.0, "Keck II", "Mauna Kea"],
25
+ [9.2, "SALT", "South African Astronomical Observatory"],
26
+ [9.2, "Hobby-Eberly", "Mt. Fowlkes"],
27
+ [8.4, "Large Binocular Telescope", "Mt. Graham"],
28
+ [8.3, "Subaru", "Mauna Kea"],
29
+ [8.2, "Antu", "Cerro Paranal"],
30
+ [8.2, "Kueyen", "Cerro Paranal"],
31
+ [8.2, "Melipal", "Cerro Paranal"],
32
+ [8.2, "Yepun", "Cerro Paranal"],
33
+ [8.1, "Gemini North", "Mauna Kea"],
34
+ [8.1, "Gemini South", "Cerro Pachon"],
35
+ [6.5, "MMT", "Mt. Hopkins"],
36
+ [6.5, "Walter Baade", "La Serena"],
37
+ [6.5, "Landon Clay", "La Serena"],
38
+ [6.0, "Bolshoi Teleskop Azimutalnyi", "Nizhny Arkhyz"],
39
+ [6.0, "LZT", "British Columbia"],
40
+ [5.0, "Hale", "Palomar Mountain"],
41
+ [4.3, "Dicovery Channel", "Lowell Observatory"],
42
+ [4.2, "William Herschel", "La Palma"],
43
+ [4.2, "SOAR", "Cerro Pachon"],
44
+ [4.2, "LAMOST", "Xinglong Station"],
45
+ [4.0, "Victor Blanco", "Cerro Tololo"],
46
+ [4.0, "Vista", "Cerro Paranal"],
47
+ [3.9, "Anglo-Australian", "Coonabarabran"],
48
+ [3.8, "Mayall", "Kitt Peak"],
49
+ [3.8, "UKIRT", "Mauna Kea"],
50
+ [3.6, "360", "Cerro La Silla"],
51
+ [3.6, "Canada-France-Hawaii", "Mauna Kea"],
52
+ [3.6, "Telescopio Nazionale Galileo", "La Palma"],
53
+ [3.5, "MPI-CAHA", "Calar Alto"],
54
+ [3.5, "New Technology", "Cerro La Silla"],
55
+ [3.5, "ARC", "Apache Point"],
56
+ [3.5, "WIYN", "Kitt Peak"],
57
+ [3.0, "Shane", "Mount Hamilton"],
58
+ [3.0, "NASA IRTF", "Mauna Kea"],
59
+ ]
60
+
61
+ scopes = np.zeros(
62
+ len(telescopes),
63
+ dtype=list(zip(["aperture", "name", "lat", "lon"], [float, (np.str_, 38), float, float])),
64
+ )
65
+
66
+ # name, lat (S negative), lon (W negative)
67
+ observatories = [
68
+ ["Cerro Paranal", -24, 38, -70, 24],
69
+ ["Nizhny Arkhyz", 43, 39, 41, 26],
70
+ ["Cerro La Silla", -29, 15, -70, 44],
71
+ ["Lowell Observatory", 35, 12, -111, 40],
72
+ ["Apache Point", 32, 47, -105, 49],
73
+ ["Mount Hamilton", 37, 21, -121, 38],
74
+ ["South African Astronomical Observatory", -32, 23, 20, 49],
75
+ ["Cerro Pachon", -30, 20, -70, 59],
76
+ ["Coonabarabran", -31, 17, 149, 0o4],
77
+ ["Mt. Fowlkes", 30, 40, -104, 1],
78
+ ["La Palma", 28, 46, -17, 53],
79
+ ["Mt. Graham", 32, 42, -109, 53],
80
+ ["Calar Alto", 37, 13, -2, 33],
81
+ ["British Columbia", 49, 17, -122, 34],
82
+ ["Kitt Peak", 31, 57, -111, 37],
83
+ ["La Serena", -30, 10, -70, 48],
84
+ ["Palomar Mountain", 33, 21, -116, 52],
85
+ ["Xinglong Station", 40, 23, 105, 50],
86
+ ["Mt. Hopkins", 31, 41, -110, 53],
87
+ ["Cerro Tololo", -30, 10, -70, 49],
88
+ ["Mauna Kea", 19, 50, -155, 28],
89
+ ]
90
+
91
+ # Make a nice little dict to look up the observatory positions
92
+ obs = {}
93
+ for i, ob in enumerate(observatories):
94
+ obs[ob[0]] = [
95
+ (np.abs(ob[1]) + ob[2] / 60.0) * (ob[1] / np.abs(ob[1])),
96
+ (np.abs(ob[3]) + ob[4] / 60.0) * (ob[3] / np.abs(ob[3])),
97
+ ]
98
+
99
+ for i, telescope in enumerate(telescopes):
100
+ scopes["aperture"][i] = telescope[0]
101
+ scopes["name"][i] = telescope[1]
102
+ scopes["lat"][i], scopes["lon"][i] = obs[telescope[2]]
103
+
104
+ scopes = scopes[np.where(scopes["aperture"] >= min_size)]
105
+ return scopes
106
+
107
+
108
+ class NFollowStacker(BaseStacker):
109
+ """Add the number of telescopes ('nObservatories') that could
110
+ follow up any visit at (any of the) times in timeStep,
111
+ specifying the minimum telescope size (in meters) and airmass limit.
112
+
113
+ Parameters
114
+ ----------
115
+ minSize: float, optional
116
+ The minimum telescope aperture to use, in meters. Default 3.0.
117
+ airmass_limit: float, optional
118
+ The maximum airmass allowable at the follow-up observatory.
119
+ Default 2.5.
120
+ time_steps: np.array or list of floats, optional
121
+ The timesteps to check for followup opportunities, in hours.
122
+ Default is np.arange(0.5, 12., 3.0).
123
+ mjd_col: str, optional
124
+ The exposure MJD column name. Default 'observationStartMJD'.
125
+ ra_col: str, optional
126
+ The RA column name. Default 'fieldRA'.
127
+ dec_col: str, optional
128
+ The Dec column name. Default 'fieldDec'.
129
+ raDecDeg: bool, optional
130
+ Flag whether RA/Dec are in degrees (True) or radians (False).
131
+ """
132
+
133
+ cols_added = ["nObservatories"]
134
+
135
+ def __init__(
136
+ self,
137
+ min_size=3.0,
138
+ airmass_limit=2.5,
139
+ time_steps=np.arange(0.5, 12.0, 3.0),
140
+ mjd_col="observationStartMJD",
141
+ ra_col="fieldRA",
142
+ dec_col="fieldDec",
143
+ degrees=True,
144
+ ):
145
+ self.mjd_col = mjd_col
146
+ self.ra_col = ra_col
147
+ self.dec_col = dec_col
148
+ self.degrees = degrees
149
+ self.cols_added_dtypes = [int]
150
+ self.cols_req = [self.mjd_col, self.ra_col, self.dec_col]
151
+ self.units = ["#"]
152
+ self.airmass_limit = airmass_limit
153
+ self.time_steps = time_steps
154
+ self.telescopes = find_telescopes(min_size=min_size)
155
+
156
+ def _run(self, sim_data, cols_present=False):
157
+ if cols_present:
158
+ return sim_data
159
+ sim_data["nObservatories"] = 0
160
+ if self.degrees:
161
+ ra = np.radians(sim_data[self.ra_col])
162
+ dec = np.radians(sim_data[self.dec_col])
163
+ else:
164
+ ra = sim_data[self.ra_col]
165
+ dec = sim_data[self.dec_col]
166
+ for obs in self.telescopes:
167
+ obs_got_it = np.zeros(len(sim_data[self.ra_col]), int)
168
+ obs_lon = np.radians(obs["lon"])
169
+ obs_lat = np.radians(obs["lat"])
170
+ for step in self.time_steps:
171
+ alt, az = ra_dec2_alt_az(
172
+ ra,
173
+ dec,
174
+ obs_lon,
175
+ obs_lat,
176
+ sim_data[self.mjd_col] + step / 24.0,
177
+ altonly=True,
178
+ )
179
+ airmass = 1.0 / (np.cos(np.pi / 2.0 - alt))
180
+ followed = np.where((airmass <= self.airmass_limit) & (airmass >= 1.0))
181
+ # If the observatory got an observation, save this
182
+ # into obs_got_it.
183
+ # obs_got_it will be 1 if ANY of the times got an observation.
184
+ obs_got_it[followed] = 1
185
+ # If an observatory got an observation, count it in nObservatories.
186
+ sim_data["nObservatories"] += obs_got_it
187
+ return sim_data