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,643 @@
1
+ __all__ = ("get_oorb_data_dir", "PyOrbEphemerides")
2
+
3
+ import os
4
+ import time
5
+ import warnings
6
+ from itertools import repeat
7
+
8
+ import numpy as np
9
+ import pandas as pd
10
+
11
+ try:
12
+ import pyoorb as oo
13
+
14
+ PYOORB_PRESENT = True
15
+
16
+ except ModuleNotFoundError:
17
+ PYOORB_PRESENT = False
18
+
19
+
20
+ def dtime(time_prev):
21
+ return (time.time() - time_prev, time.time())
22
+
23
+
24
+ def get_oorb_data_dir():
25
+ """Find where the oorb files should be installed"""
26
+ data_path = os.getenv("OORB_DATA")
27
+ if data_path is None:
28
+ # See if we are in a conda enviroment and can find it
29
+ conda_dir = os.getenv("CONDA_PREFIX")
30
+ if conda_dir is not None:
31
+ data_path = os.path.join(conda_dir, "share/openorb")
32
+ if not os.path.isdir(data_path):
33
+ data_path = None
34
+ os.environ["OORB_DATA"] = data_path
35
+ if data_path is None:
36
+ warnings.warn(
37
+ "Failed to find path for oorb data files. "
38
+ "No $OORB_DATA environment variable set, and they are not the usual conda spot"
39
+ )
40
+ return data_path
41
+
42
+
43
+ class PyOrbEphemerides:
44
+ """Generate ephemerides and propagate orbits,
45
+ using the python interface to Oorb.
46
+
47
+ PyOrbEphemerides handles the packing and unpacking of the fortran style
48
+ arrays that pyoorb uses, to and from more user-friendly pandas arrays.
49
+
50
+ Parameters
51
+ ----------
52
+ ephfile : `str`, optional
53
+ Planetary ephemerides file for Oorb (i.e. de430 or de405).
54
+ Default $OORB_DATA/de430.dat ($OORB_DATA = $OORB_DIR/data).
55
+
56
+ Examples
57
+ --------
58
+ Typical usage:
59
+
60
+ >>> pyephs = PyOrbEphemerides()
61
+ >>> pyephs.set_orbits(orbits)
62
+ >>> ephs = pyephs.generateEphemerides(times, timeScale, obscode)
63
+ """
64
+
65
+ def __init__(self, ephfile=None):
66
+
67
+ if not PYOORB_PRESENT:
68
+ warnings.warn("No pyoorb available, use another ephemeris generator.")
69
+ raise ModuleNotFoundError
70
+
71
+ # Set translation from timescale to OpenOrb numerical representation.
72
+ # Note all orbits are assumed to be in TT timescale.
73
+ # Also, all dates are expected to be in MJD.
74
+ self.time_scales = {"UTC": 1, "UT1": 2, "TT": 3, "TAI": 4}
75
+ self.elem_type = {"CAR": 1, "COM": 2, "KEP": 3, "DEL": 4, "EQX": 5}
76
+
77
+ # Set up oorb. Call this once.
78
+ if ephfile is None:
79
+ ephfile = os.path.join(get_oorb_data_dir(), "de430.dat")
80
+ self.ephfile = ephfile
81
+ self._init_oorb()
82
+ self.oorb_elem = None
83
+ self.orb_format = None
84
+
85
+ def _init_oorb(self):
86
+ oo.pyoorb.oorb_init(ephemeris_fname=self.ephfile)
87
+
88
+ def set_orbits(self, orbit_obj):
89
+ """Set the orbits, to be used to generate ephemerides.
90
+
91
+ Immediately calls self._convertOorbElem to translate to the
92
+ 'packed' oorb format.
93
+
94
+ Parameters
95
+ ----------
96
+ orbit_obj : `rubin_sim.moving_objects.Orbits`
97
+ The orbits to use to generate ephemerides.
98
+ """
99
+ if len(orbit_obj) == 0:
100
+ raise ValueError("There are no orbits in the Orbit object.")
101
+ self._convert_to_oorb_elem(orbit_obj.orbits, orbit_obj.orb_format)
102
+
103
+ def _convert_to_oorb_elem(self, orbit_dataframe, orb_format):
104
+ """Convert orbital elements into the numpy fortran-format
105
+ array OpenOrb requires.
106
+
107
+ The OpenOrb element format is a single array with elements:
108
+ 0 : orbitId (cannot be a string)
109
+ 1-6 : orbital elements, using radians for angles
110
+ 7 : element 'type' code
111
+ (1 = CAR, 2 = COM, 3 = KEP, 4 = DELauny, 5 = EQX (equinoctial))
112
+ 8 : epoch
113
+ 9 : timescale for epoch
114
+ (1 = UTC, 2 = UT1, 3 = TT, 4 = TAI : always assumes TT)
115
+ 10 : magHv
116
+ 11 : g
117
+
118
+ Sets self.oorb_elem, the orbit parameters in an array
119
+ formatted for OpenOrb.
120
+ """
121
+ oorb_elem = np.zeros([len(orbit_dataframe), 12], dtype=np.double, order="F")
122
+ # Put in simple values for objid, or add method to test if
123
+ # any obj_id is a string.
124
+ # NOTE THAT THIS MEANS WE'VE LOST THE OBJID
125
+ oorb_elem[:, 0] = np.arange(0, len(orbit_dataframe), dtype=int) + 1
126
+ # Add the appropriate element and epoch types:
127
+ oorb_elem[:, 7] = np.zeros(len(orbit_dataframe), float) + self.elem_type[orb_format]
128
+ oorb_elem[:, 9] = np.zeros(len(orbit_dataframe), float) + self.time_scales["TT"]
129
+ # Convert other elements INCLUDING converting inclination,
130
+ # node, argperi to RADIANS
131
+ if orb_format == "KEP":
132
+ oorb_elem[:, 1] = orbit_dataframe["a"]
133
+ oorb_elem[:, 2] = orbit_dataframe["e"]
134
+ oorb_elem[:, 3] = np.radians(orbit_dataframe["inc"])
135
+ oorb_elem[:, 4] = np.radians(orbit_dataframe["Omega"])
136
+ oorb_elem[:, 5] = np.radians(orbit_dataframe["argPeri"])
137
+ oorb_elem[:, 6] = np.radians(orbit_dataframe["meanAnomaly"])
138
+ elif orb_format == "COM":
139
+ oorb_elem[:, 1] = orbit_dataframe["q"]
140
+ oorb_elem[:, 2] = orbit_dataframe["e"]
141
+ oorb_elem[:, 3] = np.radians(orbit_dataframe["inc"])
142
+ oorb_elem[:, 4] = np.radians(orbit_dataframe["Omega"])
143
+ oorb_elem[:, 5] = np.radians(orbit_dataframe["argPeri"])
144
+ oorb_elem[:, 6] = orbit_dataframe["tPeri"]
145
+ elif orb_format == "CAR":
146
+ oorb_elem[:, 1] = orbit_dataframe["x"]
147
+ oorb_elem[:, 2] = orbit_dataframe["y"]
148
+ oorb_elem[:, 3] = orbit_dataframe["z"]
149
+ oorb_elem[:, 4] = orbit_dataframe["xdot"]
150
+ oorb_elem[:, 5] = orbit_dataframe["ydot"]
151
+ oorb_elem[:, 6] = orbit_dataframe["zdot"]
152
+ else:
153
+ raise ValueError("Unknown orbit format %s: should be COM, KEP or CAR." % orb_format)
154
+ oorb_elem[:, 8] = orbit_dataframe["epoch"]
155
+ oorb_elem[:, 10] = orbit_dataframe["H"]
156
+ oorb_elem[:, 11] = orbit_dataframe["g"]
157
+ self.oorb_elem = oorb_elem
158
+ self.orb_format = orb_format
159
+
160
+ def convert_from_oorb_elem(self):
161
+ """Translate pyoorb-style (fortran packed) orbital element array
162
+ into a pandas dataframe. Operates on self.oorb_elem.
163
+
164
+ Returns
165
+ -------
166
+ new_orbits : `pd.DataFrame`
167
+ A DataFrame with the appropriate subset of columns
168
+ relating to orbital elements.
169
+ """
170
+ if self.orb_format == "KEP":
171
+ new_orbits = pd.DataFrame(
172
+ self.oorb_elem.copy(),
173
+ columns=[
174
+ "oorbId",
175
+ "a",
176
+ "e",
177
+ "inc",
178
+ "Omega",
179
+ "argPeri",
180
+ "meanAnomaly",
181
+ "elem_type",
182
+ "epoch",
183
+ "epoch_type",
184
+ "H",
185
+ "g",
186
+ ],
187
+ )
188
+ new_orbits["meanAnomaly"] = np.degrees(new_orbits["meanAnomaly"])
189
+ elif self.orb_format == "COM":
190
+ new_orbits = pd.DataFrame(
191
+ self.oorb_elem.copy(),
192
+ columns=[
193
+ "oorbId",
194
+ "q",
195
+ "e",
196
+ "inc",
197
+ "Omega",
198
+ "argPeri",
199
+ "tPeri",
200
+ "elem_type",
201
+ "epoch",
202
+ "epoch_type",
203
+ "H",
204
+ "g",
205
+ ],
206
+ )
207
+ elif self.orb_format == "CAR":
208
+ new_orbits = pd.DataFrame(
209
+ self.oorb_elem.copy(),
210
+ columns=[
211
+ "oorbId",
212
+ "x",
213
+ "y",
214
+ "z",
215
+ "xdot",
216
+ "ydot",
217
+ "zdot",
218
+ "elem_type",
219
+ "epoch",
220
+ "epoch_type",
221
+ "H",
222
+ "g",
223
+ ],
224
+ )
225
+ else:
226
+ raise ValueError("Unknown orbit format %s: should be COM, KEP or CAR." % self.orb_format)
227
+ # Convert from radians to degrees.
228
+ if self.orb_format == "KEP" or self.orb_format == "COM":
229
+ new_orbits["inc"] = np.degrees(new_orbits["inc"])
230
+ new_orbits["Omega"] = np.degrees(new_orbits["Omega"])
231
+ new_orbits["argPeri"] = np.degrees(new_orbits["argPeri"])
232
+ # Drop columns we don't need and don't include in our standard columns.
233
+ del new_orbits["elem_type"]
234
+ del new_orbits["epoch_type"]
235
+ del new_orbits["oorbId"]
236
+ # To incorporate with original Orbits object, need to swap
237
+ # back to original obj_ids as well as put back in original SEDs.
238
+ return new_orbits
239
+
240
+ def convert_orbit_format(self, orb_format="CAR"):
241
+ """Convert orbital elements into `format`.
242
+
243
+ Example: converts from self.oorb_elem[orb_format] (such as KEP)
244
+ to oorb_format (such as CAR).
245
+
246
+ Parameters
247
+ ----------
248
+ orb_format : `str`, optional
249
+ Format to convert orbital elements into.
250
+ """
251
+ oorb_elem, err = oo.pyoorb.oorb_element_transformation(
252
+ in_orbits=self.oorb_elem, in_element_type=self.elem_type[orb_format]
253
+ )
254
+ if err != 0:
255
+ raise RuntimeError("Oorb returned error %s" % (err))
256
+ del self.oorb_elem
257
+ self.oorb_elem = oorb_elem
258
+ self.orb_format = orb_format
259
+ return
260
+
261
+ def _convert_times(self, times, time_scale="UTC"):
262
+ """Generate an oorb-format array of the times desired for the
263
+ ephemeris generation.
264
+
265
+ Parameters
266
+ ----------
267
+ times : `np.ndarray` or `float`
268
+ The ephemeris times (MJD) desired
269
+ time_scale : `str`, optional
270
+ The timescale (UTC, UT1, TT, TAI) of the ephemeris MJD values.
271
+ Default = UTC, MJD.
272
+
273
+ Returns
274
+ -------
275
+ eph_times : `np.ndarray`
276
+ The oorb-formatted 'eph_times' array.
277
+ """
278
+ if isinstance(times, float):
279
+ times = np.array([times])
280
+ if len(times) == 0:
281
+ raise ValueError("Got zero times to convert for OpenOrb")
282
+ eph_times = np.array(
283
+ list(zip(times, repeat(self.time_scales[time_scale], len(times)))),
284
+ dtype="double",
285
+ order="F",
286
+ )
287
+ return eph_times
288
+
289
+ def _generate_oorb_ephs_full(self, eph_times, obscode="I11", eph_mode="N"):
290
+ """Generate full set of ephemeris output values using Oorb.
291
+
292
+ Parameters
293
+ ----------
294
+ eph_times : `np.ndarray`
295
+ Ephemeris times in oorb format (see self.convertTimes)
296
+ obscode : `int` or `str`, optional
297
+ The observatory code for ephemeris generation.
298
+ Default=I11 (Cerro Pachon).
299
+ eph_mode : `str`, optional
300
+ What dynamical mode to use for generating ephemerides -
301
+ "N" (n-body) or "2" (2-body).
302
+
303
+ Returns
304
+ -------
305
+ ephemerides : `np.ndarray`
306
+ The oorb-formatted ephemeris array.
307
+ """
308
+ oorb_ephems, err = oo.pyoorb.oorb_ephemeris_full(
309
+ in_orbits=self.oorb_elem,
310
+ in_obscode=obscode,
311
+ in_date_ephems=eph_times,
312
+ in_dynmodel=eph_mode,
313
+ )
314
+ if err != 0:
315
+ raise RuntimeError("Oorb returned error %s" % (err))
316
+ return oorb_ephems
317
+
318
+ def _convert_oorb_ephs_full(self, oorb_ephs, by_object=True):
319
+ """Converts oorb ephemeris array to np.ndarray.
320
+
321
+ Here we convert to a numpy.ndarray, grouped either by object (default)
322
+ or by time (if by_object=False).
323
+ The resulting array is composed of columns (of each ephemeris element),
324
+ where each column is 2-d array with first axes either 'object'
325
+ or 'time'.
326
+ - if by_object = True : [ephemeris elements][object][time]
327
+ (i.e. the 'ra' column = 2-d array, where the [0] axis (length)
328
+ equals the number of ephTimes)
329
+ - if by_object = False : [ephemeris elements][time][object]
330
+ (i.e. the 'ra' column = 2-d arrays, where the [0] axis (length)
331
+ equals the number of objects)
332
+
333
+ Parameters
334
+ ----------
335
+ oorb_ephs : `np.ndarray`
336
+ The oorb-formatted ephemeris values
337
+ by_object : `bool`, optional
338
+ If True (default), resulting converted ephemerides are grouped
339
+ by object.
340
+ If False, resulting converted ephemerides are grouped by time.
341
+
342
+ Returns
343
+ -------
344
+ ephemerides : `np.ndarray`
345
+ The re-arranged ephemeris values, in a 3-d array.
346
+
347
+ Notes
348
+ -----
349
+ The oorb ephemeris array is a 3-d array organized as:
350
+ (object / times / eph@time)
351
+ [objid][time][ephemeris information @ that time] with elements
352
+ ! (1) modified julian date
353
+ ! (2) right ascension (deg)
354
+ ! (3) declination (deg)
355
+ ! (4) dra/dt sky-motion (deg/day, including cos(dec) factor)
356
+ ! (5) ddec/dt sky-motion (deg/day)
357
+ ! (6) solar phase angle (deg)
358
+ ! (7) solar elongation angle (deg)
359
+ ! (8) heliocentric distance (au)
360
+ ! (9) geocentric distance (au)
361
+ ! (10) predicted apparent V-band magnitude
362
+ ! (11) position angle for direction of motion (deg)
363
+ ! (12) topocentric ecliptic longitude (deg)
364
+ ! (13) topocentric ecliptic latitude (deg)
365
+ ! (14) opposition-centered topocentric ecliptic longitude (deg)
366
+ ! (15) opposition-centered topocentric ecliptic latitude (deg)
367
+ ! (16) heliocentric ecliptic longitude (deg)
368
+ ! (17) heliocentric ecliptic latitude (deg)
369
+ ! (18) opposition-centered heliocentric ecliptic longitude (deg)
370
+ ! (19) opposition-centered heliocentric ecliptic latitude (deg)
371
+ ! (20) topocentric object altitude (deg)
372
+ ! (21) topocentric solar altitude (deg)
373
+ ! (22) topocentric lunar altitude (deg)
374
+ ! (23) lunar phase [0...1]
375
+ ! (24) lunar elongation (deg, distance between the target and the Moon)
376
+ ! (25) heliocentric ecliptic cartesian x coordinate for the object (au)
377
+ ! (26) helio ecliptic cartesian y coordinate for the object (au)
378
+ ! (27) helio ecliptic cartesian z coordinate for the objects (au)
379
+ ! (28) helio ecliptic cartesian x rate for the object (au/day))
380
+ ! (29) helio ecliptic cartesian y rate for the object (au/day)
381
+ ! (30) helio ecliptic cartesian z rate for the objects (au/day)
382
+ ! (31) helio ecliptic cartesian coordinates for the observatory (au)
383
+ ! (32) helio ecliptic cartesian coordinates for the observatory (au)
384
+ ! (33) helio ecliptic cartesian coordinates for the observatory (au)
385
+ ! (34) true anomaly (currently only a dummy value)
386
+ """
387
+ ephs = np.swapaxes(oorb_ephs, 2, 0)
388
+ velocity = np.sqrt(ephs[3] ** 2 + ephs[4] ** 2)
389
+ if by_object:
390
+ ephs = np.swapaxes(ephs, 2, 1)
391
+ velocity = np.swapaxes(velocity, 1, 0)
392
+ # Create a numpy recarray.
393
+ names = [
394
+ "time",
395
+ "ra",
396
+ "dec",
397
+ "dradt",
398
+ "ddecdt",
399
+ "phase",
400
+ "solarelon",
401
+ "helio_dist",
402
+ "geo_dist",
403
+ "magV",
404
+ "pa",
405
+ "topo_lon",
406
+ "topo_lat",
407
+ "opp_topo_lon",
408
+ "opp_topo_lat",
409
+ "helio_lon",
410
+ "helio_lat",
411
+ "opp_helio_lon",
412
+ "opp_helio_lat",
413
+ "topo_obj_alt",
414
+ "topo_solar_alt",
415
+ "topo_lunar_alt",
416
+ "lunar_phase",
417
+ "lunar_dist",
418
+ "helio_x",
419
+ "helio_y",
420
+ "helio_z",
421
+ "helio_dx",
422
+ "helio_dy",
423
+ "helio_dz",
424
+ "obs_helio_x",
425
+ "obs_helio_y",
426
+ "obs_helio_z",
427
+ "trueAnom",
428
+ ]
429
+ arraylist = []
430
+ for i, n in enumerate(names):
431
+ arraylist.append(ephs[i])
432
+ arraylist.append(velocity)
433
+ names.append("velocity")
434
+ ephs = np.rec.fromarrays(arraylist, names=names)
435
+ return ephs
436
+
437
+ def _generate_oorb_ephs_basic(self, eph_times, obscode="I11", eph_mode="N"):
438
+ """Generate ephemerides using OOrb with two body mode.
439
+
440
+ Parameters
441
+ ----------
442
+ ephtimes : `np.ndarray`
443
+ Ephemeris times in oorb format (see self.convertTimes).
444
+ obscode : `int` or `str`, optional
445
+ The observatory code for ephemeris generation.
446
+ Default=I11 (Cerro Pachon).
447
+
448
+ Returns
449
+ -------
450
+ oorb_ephems : `np.ndarray`
451
+ The oorb-formatted ephemeris array.
452
+ """
453
+ oorb_ephems, err = oo.pyoorb.oorb_ephemeris_basic(
454
+ in_orbits=self.oorb_elem,
455
+ in_obscode=obscode,
456
+ in_date_ephems=eph_times,
457
+ in_dynmodel=eph_mode,
458
+ )
459
+ if err != 0:
460
+ raise RuntimeError("Oorb returned error %s" % (err))
461
+ return oorb_ephems
462
+
463
+ def _convert_oorb_ephs_basic(self, oorb_ephs, by_object=True):
464
+ """Converts oorb ephemeris array to numpy recarray,
465
+ with labeled columns.
466
+
467
+ Parameters
468
+ ----------
469
+ oorb_ephs : `np.ndarray`
470
+ The oorb-formatted ephemeris values
471
+ by_object : `bool`, optional
472
+ If True (default), resulting converted ephemerides are grouped
473
+ by object.
474
+ If False, resulting converted ephemerides are grouped by time.
475
+
476
+ Returns
477
+ -------
478
+ ephs : `np.ndarray`
479
+ The re-arranged ephemeris values, in a 3-d array.
480
+
481
+ Notes
482
+ -----
483
+ The oorb ephemeris array is a 3-d array organized as:
484
+ (object / times / eph@time)
485
+ [objid][time][ephemeris information @ that time] with ephemeris
486
+ elements
487
+ ! (1) modified julian date
488
+ ! (2) right ascension (deg)
489
+ ! (3) declination (deg)
490
+ ! (4) dra/dt sky-motion (deg/day, including cos(dec) factor)
491
+ ! (5) ddec/dt sky-motion (deg/day)
492
+ ! (6) solar phase angle (deg)
493
+ ! (7) solar elongation angle (deg)
494
+ ! (8) heliocentric distance (au)
495
+ ! (9) geocentric distance (au)
496
+ ! (10) predicted apparent V-band magnitude
497
+ ! (11) true anomaly (currently only a dummy value)
498
+
499
+ Here we convert to a numpy array, grouped either by object (default)
500
+ or by time (if by_object=False).
501
+ The resulting array is composed of columns (of each ephemeris element),
502
+ where each column is 2-d array with first axes either 'object'
503
+ or 'time'.
504
+ - if by_object = True : [ephemeris elements][object][time]
505
+ (i.e. the 'ra' column = 2-d array, where the [0] axis (length)
506
+ equals the number of ephTimes)
507
+ - if by_object = False : [ephemeris elements][time][object]
508
+ (i.e. the 'ra' column = 2-d arrays, where the [0] axis (length)
509
+ equals the number of objects)
510
+ """
511
+ ephs = np.swapaxes(oorb_ephs, 2, 0)
512
+ velocity = np.sqrt(ephs[3] ** 2 + ephs[4] ** 2)
513
+ if by_object:
514
+ ephs = np.swapaxes(ephs, 2, 1)
515
+ velocity = np.swapaxes(velocity, 1, 0)
516
+ # Create a numpy recarray.
517
+ names = [
518
+ "time",
519
+ "ra",
520
+ "dec",
521
+ "dradt",
522
+ "ddecdt",
523
+ "phase",
524
+ "solarelon",
525
+ "helio_dist",
526
+ "geo_dist",
527
+ "magV",
528
+ "trueAnomaly",
529
+ ]
530
+ arraylist = []
531
+ for i, n in enumerate(names):
532
+ arraylist.append(ephs[i])
533
+ arraylist.append(velocity)
534
+ names.append("velocity")
535
+ ephs = np.rec.fromarrays(arraylist, names=names)
536
+ return ephs
537
+
538
+ def generate_ephemerides(
539
+ self,
540
+ times,
541
+ time_scale="UTC",
542
+ obscode="I11",
543
+ by_object=True,
544
+ eph_mode="nbody",
545
+ eph_type="basic",
546
+ ):
547
+ """Calculate ephemerides for all orbits at times `times`.
548
+
549
+ All returned positions and angles are in degrees, velocities
550
+ are degrees/day and distances are in AU.
551
+
552
+ Parameters
553
+ ----------
554
+ times : `np.ndarray`, (N,)
555
+ Ephemeris times.
556
+ time_scale : `str`, optional
557
+ Time scale (UTC, TT, TAI) of times.
558
+ obscode : `int` or `str`, optional
559
+ The observatory code for ephemeris generation.
560
+ by_object : `bool`, optional
561
+ If True (default), resulting converted ephemerides are
562
+ grouped by object.
563
+ If False, resulting converted ephemerides are grouped by time.
564
+ eph_mode : `str`, optional
565
+ Dynamical model to use for ephemeris generation - nbody or 2body.
566
+ Accepts 'nbody', '2body', 'N' or '2'. Default nbody.
567
+ eph_type : `str`, optional
568
+ Generate full (more data) ephemerides or basic (less data)
569
+ ephemerides.
570
+ Default basic.
571
+
572
+ Returns
573
+ -------
574
+ ephemerides : `np.ndarray`
575
+ The ephemeris values, organized as chosen by the user.
576
+
577
+
578
+ Notes
579
+ -----
580
+ The returned ephemerides are a numpy array that can be grouped
581
+ by object or by time.
582
+
583
+ If they are grouped by object (by_object = True), the array
584
+ is organized as `ephemeris_values[object][time]`.
585
+ Here the "ra" column is a 2-d array where the [0] axis
586
+ length equals the number of ephemeris times.
587
+
588
+ If they are grouped by time (by_object=False), the array
589
+ is organized as `ephemeris_values[time][object]`.
590
+ Here the "ra" column is a 2-d array where the [0] axis length
591
+ equals the number of objects.
592
+ """
593
+ if eph_mode.lower() in ("nbody", "n"):
594
+ eph_mode = "N"
595
+ elif eph_mode.lower() in ("2body", "2"):
596
+ eph_mode = "2"
597
+ else:
598
+ raise ValueError("eph_mode should be 2body or nbody (or '2' or 'N').")
599
+
600
+ # t = time.time()
601
+ eph_times = self._convert_times(times, time_scale=time_scale)
602
+ if eph_type.lower() == "basic":
603
+ oorb_ephs, err = oo.pyoorb.oorb_ephemeris_basic(
604
+ in_orbits=self.oorb_elem,
605
+ in_obscode=obscode,
606
+ in_date_ephems=eph_times,
607
+ in_dynmodel=eph_mode,
608
+ )
609
+ ephs = self._convert_oorb_ephs_basic(oorb_ephs, by_object=by_object)
610
+ elif eph_type.lower() == "full":
611
+ oorb_ephs = self._generate_oorb_ephs_full(eph_times, obscode=obscode, eph_mode=eph_mode)
612
+ ephs = self._convert_oorb_ephs_full(oorb_ephs, by_object=by_object)
613
+ else:
614
+ raise ValueError("eph_type must be full or basic")
615
+ # dt, t = dtime(t)
616
+ # logging.debug("# Calculating ephemerides for %d objects over %d times
617
+ # required %f seconds"
618
+ # % (len(self.oorb_elem), len(times), dt))
619
+ return ephs
620
+
621
+ def propagate_orbits(self, new_epoch, eph_mode="nbody"):
622
+ """Propagate orbits from self.orbits.epoch to new epoch (MJD TT).
623
+
624
+ Parameters
625
+ ----------
626
+ new_epoch : `float`
627
+ MJD TT time for new epoch.
628
+ """
629
+ new_epoch = self._convert_times(new_epoch, time_scale="TT")
630
+ if eph_mode.lower() in ("nbody", "n"):
631
+ eph_mode = "N"
632
+ elif eph_mode.lower() in ("2body", "2"):
633
+ eph_mode = "2"
634
+ else:
635
+ raise ValueError("eph_mode should be 2body or nbody (or '2' or 'N').")
636
+
637
+ new_oorb_elem, err = oo.pyoorb.oorb_propagation(
638
+ in_orbits=self.oorb_elem, in_dynmodel=eph_mode, in_epoch=new_epoch
639
+ )
640
+ if err != 0:
641
+ raise RuntimeError("Orbit propagation returned error %d" % err)
642
+ self.oorb_elem = new_oorb_elem
643
+ return