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,376 @@
1
+ __all__ = ("DirectObs",)
2
+
3
+ import datetime
4
+ import logging
5
+ import warnings
6
+
7
+ import numpy as np
8
+ from rubin_scheduler.utils import angular_separation
9
+
10
+ from .base_obs import BaseObs
11
+
12
+
13
+ class DirectObs(BaseObs):
14
+ """
15
+ Generate observations of a set of moving objects:
16
+ exact ephemeris at the times of each observation.
17
+
18
+ First generates observations on a rough grid and looks for
19
+ observations within a specified tolerance
20
+ of the actual observations; for the observations which pass this cut,
21
+ generates a precise ephemeris and checks if the object is within the FOV.
22
+
23
+ Parameters
24
+ ----------
25
+ footprint : `str`, optional
26
+ Specify the footprint for the FOV.
27
+ Options include "camera", "circle", "rectangle".
28
+ 'Camera' means use the actual LSST camera footprint
29
+ (following a rough cut with a circular FOV).
30
+ Default is circular FOV.
31
+ r_fov : `float`, optional
32
+ If footprint is "circular", this is the radius of the fov (in degrees).
33
+ Default 1.75 degrees.
34
+ x_tol : `float`, optional
35
+ If footprint is "rectangular", this is half of the width of
36
+ the (on-sky) fov in the RA direction (in degrees).
37
+ Default 5 degrees.
38
+ y_tol : `float`, optional
39
+ If footprint is "rectangular", this is half of the width of
40
+ the fov in Declination (in degrees).
41
+ Default is 3 degrees
42
+ eph_mode: `str`, optional
43
+ Mode for ephemeris generation - nbody or 2body. Default is nbody.
44
+ prelim_eph_mode: str, optional
45
+ Mode for preliminary ephemeris generation, if any is done.
46
+ Default is 2body.
47
+ eph_type: `str`, optional
48
+ Type of ephemerides to generate - full or basic.
49
+ Full includes all values calculated by openorb;
50
+ Basic includes a more basic set.
51
+ Default is Basic.
52
+ (this includes enough information for most standard MAF metrics).
53
+ eph_file: `str` or None, optional
54
+ The name of the planetary ephemerides file to use in ephemeris
55
+ generation. Default (None) will use the default for PyOrbEphemerides.
56
+ obs_code: `str`, optional
57
+ Observatory code for ephemeris generation.
58
+ Default is "I11" - Cerro Pachon.
59
+ obs_time_col: `str`, optional
60
+ Name of the time column in the obsData.
61
+ Default 'observationStartMJD'.
62
+ obs_time_scale: `str`, optional
63
+ Type of timescale for MJD (TAI or UTC currently).
64
+ Default TAI.
65
+ seeing_col: `str`, optional
66
+ Name of the seeing column in the obsData.
67
+ Default 'seeingFwhmGeom'.
68
+ This should be the geometric/physical seeing as it is used
69
+ for the trailing loss calculation.
70
+ visit_exp_time_col: `str`, optional
71
+ Name of the visit exposure time column in the obsData.
72
+ Default 'visitExposureTime'.
73
+ obs_ra: `str`, optional
74
+ Name of the RA column in the obsData. Default 'fieldRA'.
75
+ obs_dec: `str`, optional
76
+ Name of the Dec column in the obsData. Default 'fieldDec'.
77
+ obs_rot_sky_pos: `str`, optional
78
+ Name of the Rotator column in the obsData. Default 'rotSkyPos'.
79
+ obs_degrees: `bool`, optional
80
+ Whether the observational data is in degrees or radians.
81
+ Default True (degrees).
82
+ outfile_name : `str`, optional
83
+ The output file name.
84
+ Default is 'lsst_obs.dat'.
85
+ obs_info : `str`, optional
86
+ A string that captures provenance information about the observations.
87
+ For example: 'baseline_v2.0_10yrs, MJD 59853-61677'
88
+ or 'baseline2018a minus NES'
89
+ Default ''.
90
+ tstep: `float`, optional
91
+ The time between initial (rough) ephemeris generation points, in days.
92
+ Default 1 day.
93
+ rough_tol: `float`, optional
94
+ The initial rough tolerance value for positions, used as a first
95
+ cut to identify potential observations (in degrees).
96
+ Default 10 degrees.
97
+ pre_comp_tol : float (2.08)
98
+ The radial tolerance to add when using pre-computed orbits. Should be
99
+ larger than the full field of view extent.
100
+ """
101
+
102
+ def __init__(
103
+ self,
104
+ footprint="camera",
105
+ r_fov=1.75,
106
+ x_tol=5,
107
+ y_tol=3,
108
+ eph_mode="nbody",
109
+ prelim_eph_mode="2body",
110
+ eph_type="basic",
111
+ obs_code="I11",
112
+ eph_file=None,
113
+ obs_time_col="observationStartMJD",
114
+ obs_time_scale="TAI",
115
+ seeing_col="seeingFwhmGeom",
116
+ visit_exp_time_col="visitExposureTime",
117
+ obs_ra="fieldRA",
118
+ obs_dec="fieldDec",
119
+ obs_rot_sky_pos="rotSkyPos",
120
+ obs_degrees=True,
121
+ outfile_name="lsst_obs.dat",
122
+ obs_info="",
123
+ tstep=1.0,
124
+ rough_tol=10.0,
125
+ verbose=False,
126
+ night_col="night",
127
+ filter_col="band",
128
+ m5_col="fiveSigmaDepth",
129
+ obs_id_col="observationId",
130
+ pre_comp_tol=2.08,
131
+ ):
132
+ super().__init__(
133
+ footprint=footprint,
134
+ r_fov=r_fov,
135
+ x_tol=x_tol,
136
+ y_tol=y_tol,
137
+ eph_mode=eph_mode,
138
+ eph_type=eph_type,
139
+ obs_code=obs_code,
140
+ eph_file=eph_file,
141
+ obs_time_col=obs_time_col,
142
+ obs_time_scale=obs_time_scale,
143
+ seeing_col=seeing_col,
144
+ visit_exp_time_col=visit_exp_time_col,
145
+ obs_ra=obs_ra,
146
+ obs_dec=obs_dec,
147
+ obs_rot_sky_pos=obs_rot_sky_pos,
148
+ obs_degrees=obs_degrees,
149
+ outfile_name=outfile_name,
150
+ obs_info=obs_info,
151
+ )
152
+ self.verbose = verbose
153
+ self.pre_comp_tol = pre_comp_tol
154
+ self.filter_col = filter_col
155
+ self.night_col = night_col
156
+ self.m5_col = m5_col
157
+ self.obs_id_col = obs_id_col
158
+ self.tstep = tstep
159
+ self.rough_tol = rough_tol
160
+ if prelim_eph_mode not in ("2body", "nbody"):
161
+ raise ValueError("Ephemeris generation must be 2body or nbody.")
162
+ self.prelim_eph_mode = prelim_eph_mode
163
+
164
+ def run(self, orbits, obs_data, object_positions=None, object_mjds=None):
165
+ """Find and write the observations of each object to disk.
166
+
167
+ For each object, a rough grid of ephemeris points are either
168
+ generated on the fly or read from a pre-calculated grid;
169
+ If the rough grids indicate that an object may be present
170
+ in an observation, then a more precise position is generated
171
+ for the time of the observation.
172
+
173
+
174
+ Parameters
175
+ ----------
176
+ orbits : `rubin_sim.moving_objects.Orbits`
177
+ The orbits for which to generate ephemerides.
178
+ obs_data : `np.ndarray`
179
+ The simulated pointing history data.
180
+ object_positions : `np.ndarray`
181
+ Pre-computed RA,dec positions for each object in orbits (degrees).
182
+ object_mjds : `np.ndarray`
183
+ MJD values for each pre-computed position.
184
+ """
185
+
186
+ # If we are trying to use pre-computed positions,
187
+ # check that the MJDs span the necessary time.
188
+ if object_mjds is not None:
189
+ if (obs_data[self.obs_time_col].min() < object_mjds.min()) | (
190
+ obs_data[self.obs_time_col].max() > object_mjds.max()
191
+ ):
192
+ warnings.warn(
193
+ "Pre-computed position times do not cover MJD range of %i-%i."
194
+ % (obs_data[self.obs_time_col].min(), obs_data[self.obs_time_col].max())
195
+ )
196
+ object_mjds = None
197
+ # calculate angular motion for each object at each timestep
198
+ # how much does it move going to time step forward
199
+ move1 = angular_separation(
200
+ object_positions["ra"][:, 0:-1],
201
+ object_positions["dec"][:, 0:-1],
202
+ object_positions["ra"][:, 1:],
203
+ object_positions["dec"][:, 1:],
204
+ )
205
+ # Need to take care of ends
206
+ d1 = object_positions["ra"] * 0
207
+ d1[:, 0:-1] = move1
208
+ d2 = object_positions["ra"] * 0
209
+ d2[:, 1:] = move1
210
+ # Now we can use a small tolerance for objects when they are moving
211
+ # slowly across the sky.
212
+ object_tol = np.maximum(d1, d2) + self.pre_comp_tol
213
+
214
+ # output dtype
215
+ names = [
216
+ "obj_id",
217
+ self.obs_id_col,
218
+ "sedname",
219
+ "time",
220
+ "ra",
221
+ "dec",
222
+ "dradt",
223
+ "ddecdt",
224
+ "phase",
225
+ "solarelon",
226
+ "helio_dist",
227
+ "geo_dist",
228
+ "magV",
229
+ "trueAnomaly",
230
+ "velocity",
231
+ "dmag_color",
232
+ "dmag_trail",
233
+ "dmag_detect",
234
+ ]
235
+ types = [int, int, "<U40"] + [float] * (len(names) - 3)
236
+
237
+ # XXX--for now, copy over some observation info. In the future,
238
+ # just index it to the observations and only transfer observationId
239
+ transfer_cols = [
240
+ self.visit_exp_time_col,
241
+ self.m5_col,
242
+ self.seeing_col,
243
+ self.obs_time_col,
244
+ self.night_col,
245
+ self.filter_col,
246
+ ]
247
+ transfer_types = [float] * (len(transfer_cols) - 2)
248
+ transfer_types += [int, "<U40"]
249
+ names += transfer_cols
250
+ types += transfer_types
251
+
252
+ output_dtype = list(zip(names, types))
253
+
254
+ # Set the times for the rough ephemeris grid.
255
+ time_step = float(self.tstep)
256
+ time_start = np.floor(obs_data[self.obs_time_col].min() + 0.16 - 0.5) - time_step
257
+ time_end = np.ceil(obs_data[self.obs_time_col].max() + 0.16 + 0.5) + time_step
258
+ rough_times = np.arange(time_start, time_end + time_step / 2.0, time_step)
259
+ if self.verbose:
260
+ logging.info("Generating preliminary ephemerides on a grid of %f day timesteps." % (time_step))
261
+ # list to hold results for each object
262
+ result = []
263
+ # save indx to match observation indx to object indx
264
+ indx_map_visit_to_object = []
265
+ # For each object, identify observations where the object is
266
+ # within the FOV (or camera footprint).
267
+ for i, sso in enumerate(orbits):
268
+ objid = sso.orbits["obj_id"].iloc[0]
269
+ sedname = sso.orbits["sed_filename"].iloc[0]
270
+ # Generate ephemerides on the rough grid.
271
+ if self.verbose:
272
+ logging.debug(
273
+ ("%d/%d id=%s : " % (i, len(orbits), objid))
274
+ + datetime.datetime.now().strftime("Prelim start: %Y-%m-%d %H:%M:%S")
275
+ + " nRoughTimes: %s" % len(rough_times)
276
+ )
277
+ # Not using pre-computed positions
278
+ if object_mjds is None:
279
+ ephs = self.generate_ephemerides(
280
+ sso,
281
+ rough_times,
282
+ eph_mode=self.prelim_eph_mode,
283
+ eph_type=self.eph_type,
284
+ )[0]
285
+ mu = ephs["velocity"]
286
+ if self.verbose:
287
+ logging.debug(
288
+ ("%d/%d id=%s : " % (i, len(orbits), objid))
289
+ + datetime.datetime.now().strftime("Prelim end: %Y-%m-%d %H:%M:%S")
290
+ + " π(median, max), min(geo_dist): %.2f, %.2f deg/day %.2f AU"
291
+ % (np.median(mu), np.max(mu), np.min(ephs["geo_dist"]))
292
+ )
293
+
294
+ # Find observations which come within roughTol of the fov.
295
+ ephs_idxs = np.searchsorted(ephs["time"], obs_data[self.obs_time_col])
296
+ rough_idx_obs = self._sso_in_circle_fov(ephs[ephs_idxs], obs_data, self.rough_tol)
297
+ else:
298
+ # Nearest neighbor search for the object_mjd closest to
299
+ # obs_data mjd
300
+ pos = np.searchsorted(object_mjds, obs_data[self.obs_time_col], side="left")
301
+ pos_right = pos - 1
302
+ object_indx = pos + 0
303
+ d_left = obs_data[self.obs_time_col] - object_mjds[pos]
304
+ d_right = obs_data[self.obs_time_col] - object_mjds[pos_right]
305
+ r_better = np.where(np.abs(d_right) < np.abs(d_left))[0]
306
+ object_indx[r_better] = pos_right[r_better]
307
+
308
+ rough_idx_obs = self._sso_in_circle_fov(
309
+ object_positions[i][object_indx],
310
+ obs_data,
311
+ self.r_fov + object_tol[i][object_indx],
312
+ )
313
+ if len(rough_idx_obs) > 0:
314
+ # Generate exact ephemerides for these times.
315
+ times = obs_data[self.obs_time_col][rough_idx_obs]
316
+ if self.verbose:
317
+ logging.debug(
318
+ ("%d/%d id=%s : " % (i, len(orbits), objid))
319
+ + datetime.datetime.now().strftime("Exact start: %Y-%m-%d %H:%M:%S")
320
+ + " nExactTimes: %s" % len(times)
321
+ )
322
+ ephs = self.generate_ephemerides(sso, times, eph_mode=self.eph_mode, eph_type=self.eph_type)[
323
+ 0
324
+ ]
325
+ logging.debug(
326
+ ("%d/%d id=%s : " % (i, len(orbits), objid))
327
+ + datetime.datetime.now().strftime("Exact end: %Y-%m-%d %H:%M:%S")
328
+ )
329
+ # Identify the objects which fell within the footprint.
330
+ idx_obs = self.sso_in_fov(ephs, obs_data[rough_idx_obs])
331
+ if self.verbose:
332
+ logging.info(
333
+ ("%d/%d id=%s : " % (i, len(orbits), objid))
334
+ + "Object in %d out of %d potential fields (%.2f%% success rate)"
335
+ % (
336
+ len(idx_obs),
337
+ len(times),
338
+ 100.0 * float(len(idx_obs)) / len(times),
339
+ )
340
+ )
341
+ object_observations = np.zeros(idx_obs.size, dtype=output_dtype)
342
+ object_observations["obj_id"] = objid
343
+ object_observations[self.obs_id_col] = obs_data[rough_idx_obs][idx_obs][self.obs_id_col]
344
+ object_observations["sedname"] = sedname
345
+
346
+ for key in ephs.dtype.names:
347
+ object_observations[key] = ephs[key][idx_obs].copy()
348
+ result.append(object_observations)
349
+ indx_map_visit_to_object.append(rough_idx_obs[idx_obs])
350
+
351
+ if len(result) > 0:
352
+ result = np.concatenate(result)
353
+ indx_map_visit_to_object = np.concatenate(indx_map_visit_to_object)
354
+ # add on any additional info we want here, dmags, etc
355
+ filterlist = np.unique(obs_data[self.filter_col][indx_map_visit_to_object])
356
+ for sname in np.unique(result["sedname"]):
357
+ dmag_color_dict = self.calc_colors(sname)
358
+ for f in filterlist:
359
+ match = np.where(
360
+ (obs_data[self.filter_col][indx_map_visit_to_object] == f)
361
+ & (result["sedname"] == sname)
362
+ )[0]
363
+ if np.size(match) > 0:
364
+ result["dmag_color"][match] = dmag_color_dict[f]
365
+ # Calculate trailing and detection loses.
366
+ result["dmag_trail"], result["dmag_detect"] = self.calc_trailing_losses(
367
+ result["velocity"],
368
+ obs_data[self.seeing_col][indx_map_visit_to_object],
369
+ obs_data[self.visit_exp_time_col][indx_map_visit_to_object],
370
+ )
371
+
372
+ # Transfer over info from pointing info array to result array
373
+ for key in transfer_cols:
374
+ result[key] = obs_data[key][indx_map_visit_to_object]
375
+
376
+ return result
@@ -0,0 +1,282 @@
1
+ #!/usr/bin/env python
2
+
3
+ __all__ = ("setup_args",)
4
+
5
+ import argparse
6
+ import logging
7
+ import os
8
+
9
+ import numpy as np
10
+
11
+ # So things don't fail on hyak
12
+ from astropy.utils import iers
13
+
14
+ import rubin_sim.moving_objects as mo
15
+ from rubin_sim.maf.batches import col_map_dict
16
+
17
+ iers.conf.auto_download = False
18
+
19
+
20
+ def setup_args(parser=None):
21
+ """Parse the command line arguments.
22
+
23
+ Parameters
24
+ ----------
25
+ parser: argparse.ArgumentParser, optional
26
+ Generally left at the default (None), but a user could set up
27
+ their own parser if desired.
28
+
29
+ Returns
30
+ -------
31
+ argparse.Namespace
32
+ The argument options.
33
+ """
34
+
35
+ if parser is None:
36
+ parser = argparse.ArgumentParser(description="Generate moving object detections.")
37
+ parser.add_argument(
38
+ "--simulation_db",
39
+ type=str,
40
+ default=None,
41
+ help="Simulation output db file (example: baseline_v2.1_10yrs.db). Default None.",
42
+ )
43
+ parser.add_argument(
44
+ "--orbit_file",
45
+ type=str,
46
+ default=None,
47
+ help="File containing the moving object orbits. "
48
+ "See https://github.com/oorb/oorb/tree/master/python#defining-orbits for "
49
+ "additional documentation on the orbit file format. Default None.",
50
+ )
51
+ parser.add_argument(
52
+ "--positions_file",
53
+ type=str,
54
+ default=None,
55
+ help="File with pre-computed 'rough' ephemerides for the objects in the orbit file."
56
+ " Default None, which will trigger computation of these rough ephemerides on-the-fly.",
57
+ )
58
+ parser.add_argument(
59
+ "--out_dir",
60
+ type=str,
61
+ default=".",
62
+ help="Output directory for moving object detections. Default '.'",
63
+ )
64
+ parser.add_argument(
65
+ "--output_file",
66
+ type=str,
67
+ default=None,
68
+ help="Output file name for moving object observations."
69
+ " Default will build out_dir/simulation_db_orbitFile_obs.npz.",
70
+ )
71
+ parser.add_argument(
72
+ "--sql_constraint",
73
+ type=str,
74
+ default="",
75
+ help="SQL constraint to use to select data from simulation_db. Default no constraint.",
76
+ )
77
+ parser.add_argument(
78
+ "--obs_info",
79
+ type=str,
80
+ default=None,
81
+ help="Additional info to write into output file. "
82
+ "The default info will combine the simulation_db name, the sqlconstraint, and "
83
+ "the name of the orbit file; obs_info is an optional addition.",
84
+ )
85
+ parser.add_argument(
86
+ "--footprint",
87
+ type=str,
88
+ default="camera",
89
+ help="Type of footprint to use to identify observations of each object. "
90
+ "Options are 'circle' (r=1.75 deg), 'rectangle', or 'camera' (camera footprint). "
91
+ "Default is 'camera'.",
92
+ )
93
+ parser.add_argument(
94
+ "--r_fov",
95
+ type=float,
96
+ default=1.75,
97
+ help="If using a circular footprint, this is the radius of the FOV (in degrees). "
98
+ "Default 1.75 deg.",
99
+ )
100
+ parser.add_argument(
101
+ "--x_tol",
102
+ type=float,
103
+ default=5,
104
+ help="If using a rectangular footprint, this is the tolerance in the RA direction "
105
+ "(in degrees). Default is 5 degrees.",
106
+ )
107
+ parser.add_argument(
108
+ "--y_tol",
109
+ type=float,
110
+ default=3,
111
+ help="If using a rectangular footprint, this is the tolerance in the Dec direction "
112
+ "(in degrees). Default is 3 degrees.",
113
+ )
114
+ parser.add_argument(
115
+ "--rough_tol",
116
+ type=float,
117
+ default=10,
118
+ help="If using direct/exact ephemeris generation, this is the tolerance for the "
119
+ "preliminary matches between ephemerides and pointings (in degrees). "
120
+ "Default 10 degrees.",
121
+ )
122
+ parser.add_argument(
123
+ "--obs_code",
124
+ type=str,
125
+ default="I11",
126
+ help="Observatory code for generating observations. " "Default is I11 (Cerro Pachon).",
127
+ )
128
+ parser.add_argument(
129
+ "--t_step",
130
+ type=float,
131
+ default=1.0,
132
+ help="Timestep between ephemeris generation for either the first (rough) stage of "
133
+ "direct ephemeris generation or the grid for linear interpolation "
134
+ "ephemerides. Default 1 day.",
135
+ )
136
+ parser.add_argument(
137
+ "--eph_mode",
138
+ type=str,
139
+ default="nbody",
140
+ help="2body or nbody mode for ephemeris generation. Default is nbody.",
141
+ )
142
+ parser.add_argument(
143
+ "--prelim_eph_mode",
144
+ type=str,
145
+ default="nbody",
146
+ help="Use either 2body or nbody for preliminary ephemeris generation in the rough "
147
+ "stage for DirectObs. Default 2body.",
148
+ )
149
+ parser.add_argument(
150
+ "--eph_type",
151
+ type=str,
152
+ default="basic",
153
+ help="Generate either 'basic' or 'full' ephemerides from OOrb. "
154
+ "See https://github.com/lsst/oorb/blob/lsst-dev/python/README.rst for details"
155
+ "of the contents of 'full' or 'basic' ephemerides. "
156
+ "Default basic.",
157
+ )
158
+ parser.add_argument(
159
+ "--log_file",
160
+ type=str,
161
+ default=None,
162
+ help="Send log output to log_file, instead of to console. (default = console)",
163
+ )
164
+ parser.add_argument("--verbose", dest="verbose", action="store_true", help="Print more output")
165
+ parser.set_defaults(verbose=False)
166
+
167
+ args = parser.parse_args()
168
+
169
+ if args.simulation_db is None:
170
+ raise ValueError("Must specify an simulation database output file.")
171
+
172
+ if args.orbit_file is None:
173
+ raise ValueError("Must specify an orbit file.")
174
+
175
+ run_name = os.path.split(args.simulation_db)[-1].replace(".db", "")
176
+
177
+ # Add these useful pieces to args.
178
+ args.orbitbase = ".".join(os.path.split(args.orbit_file)[-1].split(".")[:-1])
179
+
180
+ # Set up obs_file if not specified.
181
+ if args.output_file is None:
182
+ args.output_file = os.path.join(args.out_dir, "%s__%s_obs.npz" % (run_name, args.orbitbase))
183
+ else:
184
+ args.output_file = os.path.join(args.out_dir, args.output_file)
185
+
186
+ # Build some provenance to add to output file.
187
+ obs_info = args.simulation_db
188
+ if len(args.sql_constraint) > 0:
189
+ obs_info += " selected with sqlconstraint %s" % args.sql_constraint
190
+ obs_info += " + orbit_file %s" % args.orbitbase
191
+ if args.obs_info is not None:
192
+ obs_info += "\n# %s" % args.obs_info
193
+ args.obs_info = obs_info
194
+
195
+ return args
196
+
197
+
198
+ def make_lsst_obs():
199
+ # Parser command
200
+ args = setup_args()
201
+
202
+ # Send info and above logging messages to the console or logfile.
203
+ if args.log_file is not None:
204
+ logging.basicConfig(filename=args.log_file, level=logging.INFO)
205
+ else:
206
+ logging.basicConfig(level=logging.INFO)
207
+
208
+ # Read orbits.
209
+ orbits = mo.Orbits()
210
+ orbits.read_orbits(args.orbit_file)
211
+
212
+ if args.positions_file is not None:
213
+ position_data = np.load(args.positions_file)
214
+ object_positions = position_data["positions"].copy()
215
+ object_mjds = position_data["mjds"].copy()
216
+ position_data.close()
217
+ else:
218
+ object_positions = None
219
+ object_mjds = None
220
+ # Read pointing data
221
+ colmap = col_map_dict("fbs")
222
+ pointing_data = mo.read_observations(
223
+ args.simulation_db,
224
+ colmap,
225
+ constraint=args.sql_constraint,
226
+ dbcols=None,
227
+ )
228
+
229
+ # Check if we have "filter" or "band"
230
+ filter_col = "filter"
231
+ if filter_col not in pointing_data.dtype.names:
232
+ filter_col = "band"
233
+
234
+ d_obs = mo.DirectObs(
235
+ footprint=args.footprint,
236
+ r_fov=args.r_fov,
237
+ x_tol=args.x_tol,
238
+ y_tol=args.y_tol,
239
+ eph_mode=args.eph_mode,
240
+ prelim_eph_mode=args.prelim_eph_mode,
241
+ obs_code=args.obs_code,
242
+ eph_file=None,
243
+ eph_type=args.eph_type,
244
+ obs_time_col=colmap["mjd"],
245
+ obs_time_scale="TAI",
246
+ seeing_col=colmap["seeingGeom"],
247
+ visit_exp_time_col=colmap["exptime"],
248
+ obs_ra=colmap["ra"],
249
+ obs_dec=colmap["dec"],
250
+ obs_rot_sky_pos=colmap["rotSkyPos"],
251
+ obs_degrees=colmap["raDecDeg"],
252
+ outfile_name=None,
253
+ tstep=args.t_step,
254
+ rough_tol=args.rough_tol,
255
+ obs_info=args.obs_info,
256
+ verbose=args.verbose,
257
+ filter_col=filter_col,
258
+ )
259
+
260
+ filterlist = np.unique(pointing_data[filter_col])
261
+
262
+ d_obs.read_filters(filterlist=filterlist)
263
+ # Calculate all colors ahead of time.
264
+ sednames = np.unique(orbits.orbits["sed_filename"])
265
+ for sedname in sednames:
266
+ d_obs.calc_colors(sedname)
267
+
268
+ # Generate object observations.
269
+ object_observations = d_obs.run(
270
+ orbits,
271
+ pointing_data,
272
+ object_positions=object_positions,
273
+ object_mjds=object_mjds,
274
+ )
275
+
276
+ np.savez(
277
+ os.path.join(args.out_dir, args.output_file),
278
+ object_observations=object_observations,
279
+ info=d_obs.info,
280
+ )
281
+
282
+ # logging.info("Completed successfully.")