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,593 @@
1
+ __all__ = (
2
+ "generate_microlensing_slicer",
3
+ "MicrolensingMetric",
4
+ "microlensing_amplification",
5
+ "microlensing_amplification_fsfb",
6
+ "info_peak_before_t0",
7
+ "fisher_matrix",
8
+ "coefficients_pspl",
9
+ "coefficients_fsfb",
10
+ )
11
+
12
+ import os
13
+ from copy import deepcopy
14
+
15
+ import numpy as np
16
+ from astropy import units as u
17
+ from astropy.coordinates import SkyCoord
18
+ from rubin_scheduler.data import get_data_dir
19
+ from rubin_scheduler.utils import hpid2_ra_dec
20
+
21
+ import rubin_sim.maf.metrics as metrics
22
+ import rubin_sim.maf.slicers as slicers
23
+ from rubin_sim.maf.utils import m52snr
24
+
25
+
26
+ # Via Natasha Abrams nsabrams@college.harvard.edu
27
+ def microlensing_amplification(t, impact_parameter=1, crossing_time=1825.0, peak_time=100, blending_factor=1):
28
+ """The microlensing amplification
29
+
30
+ Parameters
31
+ ----------
32
+ t : `float`
33
+ The time of observation (days)
34
+ impact_parameter : `float`
35
+ The impact paramter (0 means big amplification)
36
+ crossing_time : `float`
37
+ Einstein crossing time (days)
38
+ peak_time : `float`
39
+ The peak time (days)
40
+ blending_factor: `float`
41
+ The blending factor where 1 is unblended
42
+ """
43
+
44
+ lightcurve_u = np.sqrt(impact_parameter**2 + ((t - peak_time) ** 2 / crossing_time**2))
45
+ amplified_mag = (lightcurve_u**2 + 2) / (
46
+ lightcurve_u * np.sqrt(lightcurve_u**2 + 4)
47
+ ) * blending_factor + (1 - blending_factor)
48
+
49
+ return amplified_mag
50
+
51
+
52
+ def microlensing_amplification_fsfb(t, impact_parameter=1, crossing_time=1825.0, peak_time=100, fs=20, fb=20):
53
+ """The microlensing amplification in terms of source flux and blend flux
54
+
55
+ Parameters
56
+ ----------
57
+ t : `float`
58
+ The time of observation (days)
59
+ impact_parameter : `float`
60
+ The impact paramter (0 means big amplification)
61
+ crossing_time : `float`
62
+ Einstein crossing time (days)
63
+ peak_time : `float`
64
+ The peak time (days)
65
+ """
66
+
67
+ lightcurve_u = np.sqrt(impact_parameter**2 + ((t - peak_time) ** 2 / crossing_time**2))
68
+ amplified_mag = (lightcurve_u**2 + 2) / (lightcurve_u * np.sqrt(lightcurve_u**2 + 4)) * fs + fb
69
+
70
+ return amplified_mag
71
+
72
+
73
+ def info_peak_before_t0(impact_parameter=1, crossing_time=100.0):
74
+ """Time of Maximum Information before peak
75
+
76
+ The point of maximum information before peak indicates when in a
77
+ lightcurve with constant snr the contribution to the
78
+ characterization of the event timescale tE is at maximum. After that
79
+ point in timem the timescale characterization is decisively improved.
80
+ via Markus Hundertmark markus.hundertmark@uni-heidelberg.de
81
+
82
+ Parameters
83
+ ----------
84
+ impact_parameter : `float`
85
+ The impact paramter (0 means big amplification)
86
+ crossing_time : `float`
87
+ Einstein crossing time (days)
88
+ """
89
+
90
+ optimal_time = (
91
+ crossing_time
92
+ * np.sqrt(
93
+ -(impact_parameter**2) + np.sqrt(9 * impact_parameter**4 + 36 * impact_parameter**2 + 4) - 2
94
+ )
95
+ / 2
96
+ )
97
+ return np.array(optimal_time)
98
+
99
+
100
+ def coefficients_pspl(t, t0, te, u0, fs, fb):
101
+ """Coefficients for calculating the first derivatives wrt t0,te,u0
102
+ in the Fisher matrix in an effective way, optimized with sympy and cse
103
+ via Markus Hundertmark markus.hundertmark@uni-heidelberg.de
104
+
105
+ Parameters
106
+ ----------
107
+ t : `float`
108
+ The time of observation (days usually as JD or HJD)
109
+ u0 : `float`
110
+ The impact parameter (0 means high magnification)
111
+ te : `float`
112
+ Einstein crossing time (days)
113
+ t0 : `float`
114
+ Time of peak (days usually as JD or HJD)
115
+ fs : `float`
116
+ Source flux (counts/s but here fs = 10.**(-0.4*mag_source)
117
+ in the respective passband)
118
+ fb : `float`
119
+ Blend flux (counts/s but here fs = 10.**(-0.4*mag_blend)
120
+ in the respective passband)
121
+ """
122
+ x0 = te ** (-2)
123
+ x1 = (t - t0) ** 2
124
+ x2 = u0**2 + x0 * x1
125
+ x3 = 1 / np.sqrt(x2)
126
+ x4 = 2 * x3
127
+ x5 = x2 + 4
128
+ x6 = fs / np.sqrt(x5)
129
+ x7 = x1 / te**3
130
+ x8 = x6 * x7
131
+ x9 = x2 + 2
132
+ x10 = x9 / x2 ** (3 / 2)
133
+ x11 = fs * x3 * x9 / x5 ** (3 / 2)
134
+ x12 = u0 * x6
135
+ x13 = x0 * (-2 * t + 2 * t0)
136
+ x14 = x13 * x6
137
+
138
+ c0 = x10 * x8 + x11 * x7 - x4 * x8
139
+ c1 = -u0 * x11 - x10 * x12 + x12 * x4
140
+ c2 = -1 / 2 * x10 * x14 - 1 / 2 * x11 * x13 + x14 * x3
141
+
142
+ return [c2, c1, c0]
143
+
144
+
145
+ def coefficients_fsfb(t, t0, te, u0, fs, fb):
146
+ """Coefficients for calculating the first derivatives wrt fs,fb
147
+ in the Fisher (information) matrix in an effective way, optimized
148
+ with sympy and cse this function needs to be evaluated for each
149
+ passband respectively.
150
+ via Markus Hundertmark markus.hundertmark@uni-heidelberg.de
151
+
152
+ Parameters
153
+ ----------
154
+ t : `float`
155
+ The time of observation (days usually as JD or HJD)
156
+ u0 : `float`
157
+ The impact parameter (0 means high magnification)
158
+ te : `float`
159
+ Einstein crossing time (days)
160
+ t0 : `float`
161
+ Time of peak (days usually as JD or HJD)
162
+ fs : `float`
163
+ Source flux (counts/s but here fs = 10.**(-0.4*mag_source)
164
+ in the respective passband)
165
+ fb : `float`
166
+ Blend flux (counts/s but here fs = 10.**(-0.4*mag_blend)
167
+ in the respective passband)
168
+ """
169
+ x0 = u0**2 + (t - t0) ** 2 / te**2
170
+ c0 = (x0 + 2) / (np.sqrt(x0) * np.sqrt(x0 + 4))
171
+ c1 = 1
172
+ return [c1, c0]
173
+
174
+
175
+ def fisher_matrix(t, t0, te, u0, fs, fb, snr, filters="ugriz", filter_name="i"):
176
+ """The Fisher (information) matrix relying on first derivatives
177
+ wrt t0,te,u0,fs,fb, relying on with cse optimized coefficents.
178
+ This implementation for the non-linear magnification is subject to the
179
+ respective underlying assumptions, i.e. relatively small uncertainties.
180
+ NB the Fisher matrix is using first derivatives, alternatively one
181
+ could consider second derivatives the resulting covariance matrix as
182
+ inverse of the Fisher matrix is a Cramer Rao lower bound of the
183
+ respective uncertainty.
184
+ The function returns the full information matrix for all t.
185
+
186
+ via Markus Hundertmark markus.hundertmark@uni-heidelberg.de
187
+
188
+ Parameters
189
+ ----------
190
+ t : `float`
191
+ The time of observation (days usually as JD or HJD)
192
+ u0 : `float`
193
+ The impact parameter (0 means high magnification)
194
+ te : `float`
195
+ Einstein crossing time (days)
196
+ t0 : `float`
197
+ Time of peak (days usually as JD or HJD)
198
+ fs : `float`
199
+ Source flux (counts/s but here fs = 10.**(-0.4*mag_source)
200
+ in the respective passband)
201
+ fb : `float`
202
+ Blend flux (counts/s but here fs = 10.**(-0.4*mag_blend)
203
+ in the respective passband)
204
+ snr : `float`
205
+ Signal to noise ratio in order to infer the flux uncertainty
206
+ """
207
+ # indices are 0:te, 1:u0, 2:t0
208
+ # 3:fs_i, 4:fb_i, 5:fs_i+1, 6: fb_i+1, etc. for ugrizy
209
+ filters = filters
210
+ npars = 2 * len(filters) + 3
211
+ fis_mat = np.zeros((npars, npars))
212
+ filter_index = np.where(filters == filter_name)[0]
213
+ # initialize result matrix
214
+ for i in range(len(t)):
215
+ t_value = t[i]
216
+ # err = flux_err[i]
217
+ matrix = np.zeros((npars, npars))
218
+ derivatives = coefficients_pspl(t_value, t0, te, u0, fs, fb)
219
+ fsfb_derivatives = 2 * len(filters) * [0]
220
+ fbdiff, fsdiff = coefficients_fsfb(t_value, t0, te, u0, fs, fb)
221
+ np.array(fsfb_derivatives)[filter_index * 2] = fsdiff
222
+ np.array(fsfb_derivatives)[filter_index * 2 + 1] = fbdiff
223
+ derivatives = derivatives + fsfb_derivatives
224
+ for idx in range(npars):
225
+ for jdx in range(idx, npars):
226
+ matrix[idx, jdx] = derivatives[idx] * derivatives[jdx]
227
+ # restore symmetrical entries
228
+ matrix = matrix + matrix.T - np.diag(np.diag(matrix))
229
+
230
+ # microlenisng_amplification function to replace
231
+ usqr = (t_value - t0) ** 2 / te**2 + u0**2
232
+ mu = (usqr + 2.0) / (usqr * (usqr + 4)) ** 0.5
233
+ # may need to check shape of snr and t
234
+ flux_err = (fs * mu + fb) / snr[i]
235
+
236
+ matrix = matrix / (flux_err**2)
237
+ fis_mat = fis_mat + matrix
238
+ return fis_mat
239
+
240
+
241
+ class MicrolensingMetric(metrics.BaseMetric):
242
+ """
243
+ Quantifies detectability of Microlensing events.
244
+ Can also return the number of datapoints within two crossing times
245
+ of the peak of event.
246
+
247
+ Parameters
248
+ ----------
249
+ metric_calc : `str`
250
+ Type of metric.
251
+ If metric_calc == 'detect', returns the number of microlensing events
252
+ detected within certain parameters.
253
+ If metric_calc == 'Npts', returns the number of points
254
+ within two crossing times of the peak of the vent.
255
+ pts_needed : `int`
256
+ Number of an object's lightcurve points required to be above the
257
+ 5-sigma limiting depth before it is considered detected.
258
+ time_before_peak: `int` or `str`
259
+ Number of days before lightcurve peak to qualify event as triggered.
260
+ If time_before_peak == 'optimal', the number of days before the
261
+ lightcurve peak is the time of maximal information.
262
+ detect: `bool`
263
+ By default we trigger which only looks at points before the peak
264
+ of the lightcurve. When detect = True, observations on either side
265
+ of the lightcurve are considered.
266
+
267
+ Notes
268
+ -----
269
+ Expects slice_point to have keys of:
270
+ peak_time : float (days)
271
+ crossing_time : float (days)
272
+ impact_parameter : float (positive)
273
+ blending_factors (optional): float (between 0 and 1)
274
+ """
275
+
276
+ def __init__(
277
+ self,
278
+ metric_name="MicrolensingMetric",
279
+ metric_calc="detect",
280
+ mjd_col="observationStartMJD",
281
+ m5_col="fiveSigmaDepth",
282
+ filter_col="band",
283
+ night_col="night",
284
+ pts_needed=2,
285
+ mag_dict=None,
286
+ detect_sigma=3.0,
287
+ time_before_peak=0,
288
+ detect=False,
289
+ **kwargs,
290
+ ):
291
+ self.metric_calc = metric_calc
292
+ if metric_calc == "detect":
293
+ self.units = "Detected, 0 or 1"
294
+ elif metric_calc == "Npts":
295
+ self.units = "Npts within 2tE"
296
+ elif metric_calc == "Fisher":
297
+ self.units = "Characterized, 0 or 1"
298
+ else:
299
+ raise Exception('metric_calc must be "detect", "Npts" or "Fisher".')
300
+ if mag_dict is None:
301
+ # Mean mag of stars in each filter from TRIstarDensity map
302
+ mag_dict = {
303
+ "u": 25.2,
304
+ "g": 25.0,
305
+ "r": 24.5,
306
+ "i": 23.4,
307
+ "z": 22.8,
308
+ "y": 22.5,
309
+ }
310
+ self.mjd_col = mjd_col
311
+ self.m5_col = m5_col
312
+ self.filter_col = filter_col
313
+ self.night_col = night_col
314
+ self.pts_needed = pts_needed
315
+ self.detect_sigma = detect_sigma
316
+ self.time_before_peak = time_before_peak
317
+ self.detect = detect
318
+ self.mags = mag_dict
319
+
320
+ cols = [self.mjd_col, self.m5_col, self.filter_col, self.night_col]
321
+ super(MicrolensingMetric, self).__init__(
322
+ col=cols, units=self.units, metric_name=metric_name + "_" + self.metric_calc, **kwargs
323
+ )
324
+
325
+ def run(self, data_slice, slice_point=None):
326
+ if self.detect is True and self.time_before_peak > 0:
327
+ raise Exception("When detect = True, time_before_peak must be zero")
328
+
329
+ # Generate the lightcurve for this object
330
+ # make t a kind of simple way
331
+ t = data_slice[self.mjd_col] - np.min(data_slice[self.night_col])
332
+ t = t - t.min()
333
+
334
+ #
335
+ # Try for if a blending factor slice was added
336
+ if "apparent_m_no_blend_u" in slice_point:
337
+ amplitudes = np.zeros(len(t))
338
+ individual_mags = True
339
+ else:
340
+ if "blending_factor" in slice_point:
341
+ amplitudes = microlensing_amplification(
342
+ t,
343
+ impact_parameter=slice_point["impact_parameter"],
344
+ crossing_time=slice_point["crossing_time"],
345
+ peak_time=slice_point["peak_time"],
346
+ blending_factor=slice_point["blending_factor"],
347
+ )
348
+ individual_mags = False
349
+ else:
350
+ amplitudes = microlensing_amplification(
351
+ t,
352
+ impact_parameter=slice_point["impact_parameter"],
353
+ crossing_time=slice_point["crossing_time"],
354
+ peak_time=slice_point["peak_time"],
355
+ )
356
+ individual_mags = False
357
+
358
+ filters = np.unique(data_slice[self.filter_col])
359
+ amplified_mags = amplitudes * 0
360
+
361
+ npars = 2 * len(filters) + 3
362
+ fis_mat = np.zeros((npars, npars))
363
+ fis_mat_wzeros = deepcopy(fis_mat)
364
+
365
+ for filtername in filters:
366
+ infilt = np.where(data_slice[self.filter_col] == filtername)[0]
367
+
368
+ if individual_mags is True:
369
+ fs = slice_point["apparent_m_no_blend_{}".format(filtername)]
370
+ fb = slice_point["apparent_m_{}".format(filtername)] - fs
371
+ amplitudes = microlensing_amplification_fsfb(
372
+ t,
373
+ impact_parameter=slice_point["impact_parameter"],
374
+ crossing_time=slice_point["crossing_time"],
375
+ peak_time=slice_point["peak_time"],
376
+ fs=fs,
377
+ fb=fb,
378
+ )
379
+ self.mags[filtername] = slice_point["apparent_m_{}".format(filtername)]
380
+ amplified_mags[infilt] = self.mags[filtername] - 2.5 * np.log10(amplitudes[infilt])
381
+
382
+ else:
383
+ amplified_mags[infilt] = self.mags[filtername] - 2.5 * np.log10(amplitudes[infilt])
384
+
385
+ # The SNR of each point in the light curve
386
+ snr = m52snr(amplified_mags, data_slice[self.m5_col])
387
+ # The magnitude uncertainties that go with amplified mags
388
+ mag_uncert = 2.5 * np.log10(1 + 1.0 / snr)
389
+
390
+ n_pre = []
391
+ n_post = []
392
+ for filtername in filters:
393
+ if self.metric_calc == "detect":
394
+ if self.time_before_peak == "optimal":
395
+ time_before_peak_optimal = info_peak_before_t0(
396
+ slice_point["impact_parameter"], slice_point["crossing_time"]
397
+ )
398
+ # observations pre-peak and in the given filter
399
+ infilt = np.where(
400
+ (data_slice[self.filter_col] == filtername)
401
+ & (t < (slice_point["peak_time"] - time_before_peak_optimal))
402
+ )[0]
403
+
404
+ else:
405
+ # observations pre-peak and in the given filter
406
+ infilt = np.where(
407
+ (data_slice[self.filter_col] == filtername)
408
+ & (t < (slice_point["peak_time"] - self.time_before_peak))
409
+ )[0]
410
+
411
+ # observations post-peak and in the given filter
412
+ outfilt = np.where(
413
+ (data_slice[self.filter_col] == filtername) & (t > slice_point["peak_time"])
414
+ )[0]
415
+ # Broadcast to calc the mag_i - mag_j
416
+ diffs = amplified_mags[infilt] - amplified_mags[infilt][:, np.newaxis]
417
+ diffs_uncert = np.sqrt(mag_uncert[infilt] ** 2 + mag_uncert[infilt][:, np.newaxis] ** 2)
418
+ diffs_post = amplified_mags[outfilt] - amplified_mags[outfilt][:, np.newaxis]
419
+ diffs_post_uncert = np.sqrt(
420
+ mag_uncert[outfilt] ** 2 + mag_uncert[outfilt][:, np.newaxis] ** 2
421
+ )
422
+
423
+ # Calculating this as a catalog-level detection. In theory,
424
+ # we could have a high SNR template image, so there would be
425
+ # little to no additional uncertianty from the subtraction.
426
+
427
+ sigma_above = np.abs(diffs) / diffs_uncert
428
+ sigma_above_post = np.abs(diffs_post) / diffs_post_uncert
429
+ # divide by 2 because array has i,j and j,i
430
+ n_above = np.size(np.where(sigma_above > self.detect_sigma)[0]) / 2
431
+ n_pre.append(n_above)
432
+ n_above_post = np.size(np.where(sigma_above_post > self.detect_sigma)[0]) / 2
433
+ n_post.append(n_above_post)
434
+
435
+ elif self.metric_calc == "Npts":
436
+ # observations pre-peak and in the given filter within 2tE
437
+ infilt = np.where(
438
+ (data_slice[self.filter_col] == filtername)
439
+ & (t < (slice_point["peak_time"]))
440
+ & (t > (slice_point["peak_time"] - slice_point["crossing_time"]))
441
+ & (snr > self.detect_sigma)
442
+ )[0]
443
+ # observations post-peak and in the given filter within 2tE
444
+ outfilt = np.where(
445
+ (data_slice[self.filter_col] == filtername)
446
+ & (t > (slice_point["peak_time"]))
447
+ & (t < (slice_point["peak_time"] + slice_point["crossing_time"]))
448
+ & (snr > self.detect_sigma)
449
+ )[0]
450
+ n_pre.append(len(infilt))
451
+ n_post.append(len(outfilt))
452
+
453
+ elif self.metric_calc == "Fisher":
454
+ if individual_mags is True:
455
+ fs = slice_point["apparent_m_no_blend_{}".format(filtername)]
456
+ fb = slice_point["apparent_m_{}".format(filtername)] - fs
457
+ else:
458
+ fs = self.mags[filtername]
459
+ # assuming that in populated areas of the galaxy
460
+ # the blend fraction is 0.5
461
+ fb = fs
462
+
463
+ fis_mat = fis_mat_wzeros + fisher_matrix(
464
+ t[infilt],
465
+ t0=slice_point["peak_time"],
466
+ te=slice_point["crossing_time"],
467
+ u0=slice_point["impact_parameter"],
468
+ fs=fs,
469
+ fb=fb,
470
+ snr=snr[infilt],
471
+ filters=filters,
472
+ filter_name=filtername,
473
+ )
474
+
475
+ # We remove entries if there's no data in a filter
476
+ # which would keep it from being inverted
477
+ # detectable information in dimensions:
478
+ fis_mat_wzeros = deepcopy(fis_mat)
479
+ mask_idx = np.where(np.diag(fis_mat) == 0)
480
+ fis_mat = np.delete(fis_mat, mask_idx[0], 0)
481
+ fis_mat = np.delete(fis_mat, mask_idx[0], 1)
482
+ try:
483
+ cov = np.linalg.inv(fis_mat)
484
+ sigmat_e_t_e = cov[0, 0] ** 0.5 / slice_point["crossing_time"]
485
+ # sigmau0_u0 = cov[1, 1] ** 0.5
486
+ # / slice_point["impact_parameter"]
487
+ # corr_btwn_t_eu0 = cov[0, 1] /
488
+ # (slice_point["crossing_time"]
489
+ # * slice_point["impact_parameter"])
490
+ except np.linalg.LinAlgError:
491
+ sigmat_e_t_e = np.inf
492
+ # sigmau0_u0 = np.inf
493
+ # corr_btwn_t_eu0 = np.inf
494
+
495
+ npts = np.sum(n_pre)
496
+ npts_post = np.sum(n_post)
497
+ if self.metric_calc == "detect":
498
+ if self.detect is True:
499
+ if npts >= self.pts_needed and npts_post >= self.pts_needed:
500
+ return 1
501
+ else:
502
+ return 0
503
+ else:
504
+ if npts >= self.pts_needed:
505
+ return 1
506
+ else:
507
+ return 0
508
+ elif self.metric_calc == "Npts":
509
+ return npts + npts_post
510
+ elif self.metric_calc == "Fisher":
511
+ # cutoff of sigmat_e_t_e < 0.1 for
512
+ # values determined by the 3sigma of
513
+ # pubished planet candidates
514
+ return sigmat_e_t_e
515
+
516
+
517
+ def generate_microlensing_slicer(
518
+ min_crossing_time=1,
519
+ max_crossing_time=10,
520
+ t_start=1,
521
+ t_end=3652,
522
+ n_events=10000,
523
+ seed=42,
524
+ nside=128,
525
+ filtername="r",
526
+ ):
527
+ """Generate a UserPointSlicer with a population of microlensing events.
528
+ To be used with MicrolensingMetric
529
+
530
+ Parameters
531
+ ----------
532
+ min_crossing_time : `float`
533
+ The minimum crossing time for the events generated (days)
534
+ max_crossing_time : `float`
535
+ The max crossing time for the events generated (days)
536
+ t_start : `float`
537
+ The night to start generating peaks (days)
538
+ t_end : `float`
539
+ The night to end generating peaks (days)
540
+ n_events : `int`
541
+ Number of microlensing events to generate
542
+ seed : `float`
543
+ Random number seed
544
+ nside : `int`
545
+ HEALpix nside, used to pick which stellar density map to load
546
+ filtername : `str`
547
+ The filter to use for the stellar density map
548
+
549
+ Returns
550
+ -------
551
+ slicer : `maf.UserPointsSlicer`
552
+ A slicer populated by microlensing events
553
+ (each slice_point is a different event)
554
+ """
555
+ # Seed the random number generator and generate random parameters
556
+ rng = np.random.default_rng(seed)
557
+ crossing_times = rng.uniform(low=min_crossing_time, high=max_crossing_time, size=n_events)
558
+ peak_times = rng.uniform(low=t_start, high=t_end, size=n_events)
559
+ impact_paramters = rng.uniform(low=0, high=1, size=n_events)
560
+
561
+ map_dir = os.path.join(get_data_dir(), "maps", "TriMaps")
562
+ data = np.load(os.path.join(map_dir, "TRIstarDensity_%s_nside_%i.npz" % (filtername, nside)))
563
+ star_density = data["starDensity"].copy()
564
+ # magnitude bins
565
+ bins = data["bins"].copy()
566
+ data.close()
567
+
568
+ star_mag = 22
569
+ bin_indx = np.where(bins[1:] >= star_mag)[0].min()
570
+ density_used = star_density[:, bin_indx].ravel()
571
+ order = np.argsort(density_used)
572
+ # I think the model might have a few outliers at the extreme,
573
+ # let's truncate it a bit
574
+ density_used[order[-10:]] = density_used[order[-11]]
575
+
576
+ # now, let's draw N from that distribution squared
577
+ dist = density_used[order] ** 2
578
+ cumm_dist = np.cumsum(dist)
579
+ cumm_dist = cumm_dist / np.max(cumm_dist)
580
+ uniform_draw = rng.uniform(size=n_events)
581
+ indexes = np.floor(np.interp(uniform_draw, cumm_dist, np.arange(cumm_dist.size)))
582
+ hp_ids = order[indexes.astype(int)]
583
+ gal_l, gal_b = hpid2_ra_dec(nside, hp_ids, nest=True)
584
+ c = SkyCoord(l=gal_l * u.deg, b=gal_b * u.deg, frame="galactic").transform_to("icrs")
585
+ ra, dec = c.ra.deg, c.dec.deg
586
+ # Set up the slicer to evaluate the catalog we just made
587
+ slicer = slicers.UserPointsSlicer(ra, dec, lat_lon_deg=True, badval=0)
588
+ # Add any additional information about each object to the slicer
589
+ slicer.slice_points["peak_time"] = peak_times
590
+ slicer.slice_points["crossing_time"] = crossing_times
591
+ slicer.slice_points["impact_parameter"] = impact_paramters
592
+
593
+ return slicer
@@ -0,0 +1,43 @@
1
+ # Example for numObsInSurveyTimeOverlap
2
+ # Somayeh Khakpash - Lehigh University
3
+ # Last edited : 10/21/2020
4
+ # Calculates number of observations during simultaneous windows of another
5
+ # survey.
6
+ # SurveyObsWin is the list of the survey observing window/inter-seasonal
7
+ # gap intervals. It should be in the format:
8
+ # SurveyObsWin = [ [YYYY-MM-DD, YYYY-MM-DD] ,
9
+ # [YYYY-MM-DD, YYYY-MM-DD] , ... , [YYYY-MM-DD, YYYY-MM-DD] ]
10
+
11
+ __all__ = ("NumObsInSurveyTimeOverlapMetric",)
12
+
13
+ import numpy as np
14
+ from astropy.time import Time
15
+
16
+ from rubin_sim.maf.metrics import BaseMetric
17
+
18
+
19
+ class NumObsInSurveyTimeOverlapMetric(BaseMetric):
20
+ def __init__(
21
+ self,
22
+ survey_obs_win,
23
+ time_col="observationStartMJD",
24
+ metric_name="NumObsInSurveyTimeOverlapMetric",
25
+ **kwargs,
26
+ ):
27
+ self.time_col = time_col
28
+ self.metric_name = metric_name
29
+ self.survey_obs_win = survey_obs_win
30
+ super(NumObsInSurveyTimeOverlapMetric, self).__init__(col=time_col, metric_name=metric_name, **kwargs)
31
+
32
+ def run(self, data_slice, slice_point=None):
33
+ n__obs = 0
34
+ for interval in self.survey_obs_win:
35
+ start_interval = Time(interval[0] + " 00:00:00")
36
+ end_interval = Time(interval[1] + " 00:00:00")
37
+ index = np.where(
38
+ (data_slice[self.time_col] > start_interval.mjd)
39
+ & (data_slice[self.time_col] < end_interval.mjd)
40
+ )[0]
41
+ n__obs = n__obs + np.size(index)
42
+
43
+ return n__obs
@@ -0,0 +1,51 @@
1
+ # Example for PeriodicMetric
2
+ # Mike Lund - Vanderbilt University
3
+ # mike.lund@gmail.com
4
+ # Last edited 3/10/2015
5
+ # Motivation: The detection of periodic signals can be examined by
6
+ # using canonical signals and attempted to recover these.
7
+ # However, a more general approach would be to examine the strength in
8
+ # signal that is lost as a result of poor phase coverage.
9
+ # This metric calculates the spectral window function for a set of
10
+ # scheduled observations. The largest peak at a nonzero frequency is
11
+ # used as a proxy to quantify how much power is
12
+ # lost to other frequencies. Full phase coverage will result in a value of 1.
13
+ # We refer to this as the Periodic Purity Function.
14
+
15
+ __all__ = ("PeriodicMetric",)
16
+
17
+ import numpy as np
18
+
19
+ from rubin_sim.maf.metrics import BaseMetric
20
+
21
+
22
+ class PeriodicMetric(BaseMetric):
23
+ """From a set of observation times, uses code provided by Robert Siverd
24
+ (LCOGT) to calculate the spectral window function.
25
+ """
26
+
27
+ def __init__(self, time_col="expMJD", **kwargs):
28
+ self.time_col = time_col
29
+ super(PeriodicMetric, self).__init__(col=[self.time_col], **kwargs)
30
+
31
+ def run(self, data_slice, slice_point=None):
32
+ frq_pts = 30000.0
33
+ max_frq = 25.0
34
+ times = data_slice[self.time_col]
35
+ times = times - times[0] # change times to smaller numbers
36
+ use_jd = np.array(times)
37
+ window_frq = np.arange(frq_pts) * max_frq / frq_pts
38
+ window_val = np.zeros_like(window_frq, dtype="float")
39
+ for x, frq in enumerate(window_frq):
40
+ window_val[x] = np.sum(np.cos(-2.0 * np.pi * frq * use_jd))
41
+ window_val /= np.float(use_jd.size)
42
+ secondpeak = np.sort(window_val)[-2]
43
+ totalsum = (np.sum(window_val) - np.sort(window_val)[-1]) / (frq_pts - 1)
44
+ data = np.asarray([secondpeak, totalsum])
45
+ return data
46
+
47
+ def reduce_peak(self, data):
48
+ return 1.0 - data[0]
49
+
50
+ def reduce_sum(self, data):
51
+ return data[1]