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,188 @@
1
+ import os
2
+ import shutil
3
+ import tempfile
4
+ import unittest
5
+ import warnings
6
+
7
+ import numpy as np
8
+ from rubin_scheduler.data import get_data_dir
9
+
10
+ from rubin_sim.moving_objects import ChebyFits, Orbits
11
+
12
+ ROOT = os.path.abspath(os.path.dirname(__file__))
13
+
14
+
15
+ @unittest.skip("Temporary skip until ephemerides replaced")
16
+ class TestChebyFits(unittest.TestCase):
17
+ def setUp(self):
18
+ self.testdir = os.path.join(get_data_dir(), "tests", "orbits_testdata")
19
+ self.scratch_dir = tempfile.mkdtemp(dir=ROOT, prefix="TestChebyFits-")
20
+ self.orbits = Orbits()
21
+ self.orbits.read_orbits(os.path.join(self.testdir, "test_orbitsMBA.s3m"))
22
+ self.cheb = ChebyFits(
23
+ self.orbits,
24
+ 54800,
25
+ 30,
26
+ ngran=64,
27
+ sky_tolerance=2.5,
28
+ n_decimal=10,
29
+ n_coeff_position=14,
30
+ )
31
+ self.assertEqual(self.cheb.ngran, 64)
32
+
33
+ def tearDown(self):
34
+ del self.orbits
35
+ del self.cheb
36
+ if os.path.exists(self.scratch_dir):
37
+ shutil.rmtree(self.scratch_dir)
38
+
39
+ def test_precompute_multipliers(self):
40
+ # Precompute multipliers is done as an automatic step in __init__.
41
+ # After setting up self.cheb, these multipliers should all exist.
42
+ for key in self.cheb.n_coeff:
43
+ self.assertTrue(key in self.cheb.multipliers)
44
+
45
+ def test_set_segment_length(self):
46
+ # Expect MBAs with standard ngran and tolerance to have
47
+ # length ~2.0 days.
48
+ self.cheb.calc_segment_length()
49
+ self.assertAlmostEqual(self.cheb.length, 2.0)
50
+ # Test that we can set it to other values which fit into
51
+ # the 30 day window.
52
+ self.cheb.calc_segment_length(length=1.5)
53
+ self.assertEqual(self.cheb.length, 1.5)
54
+ # Test that we if we try to set it to a value which does not
55
+ # fit into the 30 day window,
56
+ # that the actual value used is different - and smaller.
57
+ self.cheb.calc_segment_length(length=1.9)
58
+ self.assertTrue(self.cheb.length < 1.9)
59
+ # Test that we get a warning about the residuals if we try
60
+ # to set the length to be too long.
61
+ with warnings.catch_warnings(record=True) as w:
62
+ self.cheb.calc_segment_length(length=5.0)
63
+ self.assertTrue(len(w), 1)
64
+ # Now check granularity works for other orbit types
65
+ # (which would have other standard lengths).
66
+ # Check for multiple orbit types.
67
+ for orbit_file in [
68
+ "test_orbitsMBA.s3m",
69
+ "test_orbitsOuter.s3m",
70
+ "test_orbitsNEO.s3m",
71
+ ]:
72
+ self.orbits.read_orbits(os.path.join(self.testdir, orbit_file))
73
+ t_start = self.orbits.orbits["epoch"].iloc[0]
74
+ cheb = ChebyFits(self.orbits, t_start, 30, ngran=64, n_decimal=2)
75
+ # And that we should converge for a variety of other tolerances.
76
+ for sky_tolerance in (2.5, 5.0, 10.0, 100.0, 1000.0, 20000.0):
77
+ cheb.sky_tolerance = sky_tolerance
78
+ cheb.calc_segment_length()
79
+ pos_resid, ratio = cheb._test_residuals(cheb.length)
80
+ self.assertTrue(pos_resid < sky_tolerance)
81
+ self.assertEqual((cheb.length * 100) % 1, 0)
82
+ # print('final', orbit_file, sky_tolerance, pos_resid,
83
+ # cheb.length, ratio)
84
+ # And check for challenging 'impactors'.
85
+ for orbit_file in ["test_orbitsImpactors.s3m"]:
86
+ self.orbits.read_orbits(os.path.join(self.testdir, orbit_file))
87
+ t_start = self.orbits.orbits["epoch"].iloc[0]
88
+ cheb = ChebyFits(self.orbits, t_start, 30, ngran=64, n_decimal=10)
89
+ # And that we should converge for a variety of other tolerances.
90
+ for sky_tolerance in (2.5, 10.0, 100.0):
91
+ cheb.sky_tolerance = sky_tolerance
92
+ cheb.calc_segment_length()
93
+ pos_resid, ratio = cheb._test_residuals(cheb.length)
94
+ self.assertTrue(pos_resid < sky_tolerance)
95
+ # print('final', orbit_file, sky_tolerance, pos_resid,
96
+ # cheb.length, ratio)
97
+
98
+ @unittest.skip("Skipping because it has a strange platform-dependent failure")
99
+ def test_segments(self):
100
+ # Test that we can create segments.
101
+ self.cheb.calc_segment_length(length=1.0)
102
+ times = self.cheb.make_all_times()
103
+ self.cheb.generate_ephemerides(times)
104
+ self.cheb.calc_segments()
105
+ # We expect calculated coefficients to have the following keys:
106
+ coeff_keys = [
107
+ "obj_id",
108
+ "t_start",
109
+ "t_end",
110
+ "ra",
111
+ "dec",
112
+ "geo_dist",
113
+ "vmag",
114
+ "elongation",
115
+ ]
116
+ for k in coeff_keys:
117
+ self.assertTrue(k in self.cheb.coeffs.keys())
118
+ # And in this case, we had a 30 day timespan with 1 day segments
119
+ # (one day segments should be more than enough to meet
120
+ # 2.5mas tolerance, so not subdivided)
121
+ self.assertEqual(len(self.cheb.coeffs["t_start"]), 30 * len(self.orbits))
122
+ # And we used 14 coefficients for ra and dec.
123
+ self.assertEqual(len(self.cheb.coeffs["ra"][0]), 14)
124
+ self.assertEqual(len(self.cheb.coeffs["dec"][0]), 14)
125
+
126
+ def test_write(self):
127
+ # Test that we can write the output to files.
128
+ self.cheb.calc_segment_length()
129
+ self.cheb.generate_ephemerides(self.cheb.make_all_times())
130
+ self.cheb.calc_segments()
131
+ coeff_name = os.path.join(self.scratch_dir, "coeff1.txt")
132
+ resid_name = os.path.join(self.scratch_dir, "resid1.txt")
133
+ failed_name = os.path.join(self.scratch_dir, "failed1.txt")
134
+ self.cheb.write(coeff_name, resid_name, failed_name)
135
+ self.assertTrue(os.path.isfile(coeff_name))
136
+ self.assertTrue(os.path.isfile(resid_name))
137
+
138
+
139
+ @unittest.skip("Temporary skip until ephemerides replaced")
140
+ class TestRun(unittest.TestCase):
141
+ def setUp(self):
142
+ self.testdir = os.path.join(get_data_dir(), "tests", "orbits_testdata")
143
+ self.scratch_dir = tempfile.mkdtemp(dir=ROOT, prefix="TestChebyFits-")
144
+ self.orbits = Orbits()
145
+ self.orbits.read_orbits(os.path.join(self.testdir, "test_orbitsMBA.s3m"))
146
+
147
+ def tearDown(self):
148
+ del self.orbits
149
+ if os.path.exists(self.scratch_dir):
150
+ shutil.rmtree(self.scratch_dir)
151
+
152
+ def test_run_through(self):
153
+ # Set up chebyshev fitter.
154
+ t_start = self.orbits.orbits.epoch.iloc[0]
155
+ interval = 30
156
+ cheb = ChebyFits(self.orbits, t_start, interval, ngran=64, sky_tolerance=2.5, n_decimal=10)
157
+ # Set granularity. Use an value that will be too long,
158
+ # to trigger recursion below.
159
+ with warnings.catch_warnings():
160
+ warnings.simplefilter("ignore")
161
+ cheb.calc_segment_length(length=10.0)
162
+ # Run through segments.
163
+ cheb.calc_segments()
164
+ self.assertEqual(len(np.unique(cheb.coeffs["obj_id"])), len(self.orbits))
165
+ # Write outputs.
166
+ coeff_name = os.path.join(self.scratch_dir, "coeff2.txt")
167
+ resid_name = os.path.join(self.scratch_dir, "resid2.txt")
168
+ failed_name = os.path.join(self.scratch_dir, "failed2.txt")
169
+ cheb.write(coeff_name, resid_name, failed_name)
170
+ # Test that the segments for each individual object fit
171
+ # together start/end.
172
+ for k in cheb.coeffs:
173
+ cheb.coeffs[k] = np.array(cheb.coeffs[k])
174
+ for obj_id in np.unique(cheb.coeffs["obj_id"]):
175
+ condition = cheb.coeffs["obj_id"] == obj_id
176
+ te_prev = t_start
177
+ for ts, te in zip(cheb.coeffs["t_start"][condition], cheb.coeffs["t_end"][condition]):
178
+ # Test that the start of the current interval =
179
+ # the end of the previous interval.
180
+ self.assertEqual(te_prev, ts)
181
+ te_prev = te
182
+ # Test that the end of the last interval is equal to the end
183
+ # of the total interval
184
+ self.assertEqual(te, t_start + interval)
185
+
186
+
187
+ if __name__ == "__main__":
188
+ unittest.main()
@@ -0,0 +1,76 @@
1
+ import unittest
2
+
3
+ import numpy as np
4
+
5
+ from rubin_sim.moving_objects import chebeval, chebfit, make_cheb_matrix
6
+
7
+
8
+ class TestChebgrid(unittest.TestCase):
9
+ def test_raise_error(self):
10
+ x = np.linspace(-1, 1, 9)
11
+ y = np.sin(x)
12
+ dy = np.cos(x)
13
+ p, resid, rms, maxresid = chebfit(x, y, dy, n_poly=4)
14
+ with self.assertRaises(RuntimeError):
15
+ chebeval(np.linspace(-1, 1, 17), p, interval=[1, 2, 3])
16
+
17
+ def test_eval(self):
18
+ x = np.linspace(-1, 1, 9)
19
+ y = np.sin(x)
20
+ dy = np.cos(x)
21
+ p, resid, rms, maxresid = chebfit(x, y, dy, n_poly=4)
22
+ yy_w_vel, vv = chebeval(np.linspace(-1, 1, 17), p)
23
+ yy_wout_vel, vv = chebeval(np.linspace(-1, 1, 17), p, do_velocity=False)
24
+ self.assertTrue(np.allclose(yy_wout_vel, yy_w_vel))
25
+ # Test that we get a nan for a value outside the range of the
26
+ # 'interval', if mask=True
27
+ yy_w_vel, vv = chebeval(np.linspace(-2, 1, 17), p, mask=True)
28
+ self.assertTrue(
29
+ np.isnan(yy_w_vel[0]),
30
+ msg="Expected NaN for masked/out of range value, but got %.2e" % (yy_w_vel[0]),
31
+ )
32
+
33
+ def test_ends_locked(self):
34
+ x = np.linspace(-1, 1, 9)
35
+ y = np.sin(x)
36
+ dy = np.cos(x)
37
+ for polynomial in range(4, 10):
38
+ p, resid, rms, maxresid = chebfit(x, y, dy, n_poly=4)
39
+ yy, vv = chebeval(np.linspace(-1, 1, 17), p)
40
+ self.assertAlmostEqual(yy[0], y[0], places=13)
41
+ self.assertAlmostEqual(yy[-1], y[-1], places=13)
42
+ self.assertAlmostEqual(vv[0], dy[0], places=13)
43
+ self.assertAlmostEqual(vv[-1], dy[-1], places=13)
44
+
45
+ def test_accuracy(self):
46
+ """If n_poly is greater than number of values being fit,
47
+ then fit should be exact."""
48
+ x = np.linspace(0, np.pi, 9)
49
+ y = np.sin(x)
50
+ dy = np.cos(x)
51
+ p, resid, rms, maxresid = chebfit(x, y, dy, n_poly=16)
52
+ yy, vv = chebeval(x, p, interval=np.array([0, np.pi]))
53
+ self.assertTrue(np.allclose(yy, y, rtol=1e-13))
54
+ self.assertTrue(np.allclose(vv, dy, rtol=1e-13))
55
+ self.assertLess(np.sum(resid), 1e-13)
56
+
57
+ def test_accuracy_prefit_c1c2(self):
58
+ """If n_poly is greater than number of values being fit,
59
+ then fit should be exact."""
60
+ NPOINTS = 8
61
+ NPOLY = 16
62
+ x = np.linspace(0, np.pi, NPOINTS + 1)
63
+ y = np.sin(x)
64
+ dy = np.cos(x)
65
+ xmatrix, dxmatrix = make_cheb_matrix(NPOINTS + 1, NPOLY)
66
+ p, resid, rms, maxresid = chebfit(
67
+ x, y, dy, x_multiplier=xmatrix, dx_multiplier=dxmatrix, n_poly=NPOLY
68
+ )
69
+ yy, vv = chebeval(x, p, interval=np.array([0, np.pi]))
70
+ self.assertTrue(np.allclose(yy, y, rtol=1e-13))
71
+ self.assertTrue(np.allclose(vv, dy, rtol=1e-13))
72
+ self.assertLess(np.sum(resid), 1e-13)
73
+
74
+
75
+ if __name__ == "__main__":
76
+ unittest.main()
@@ -0,0 +1,245 @@
1
+ import os
2
+ import shutil
3
+ import tempfile
4
+ import unittest
5
+ import warnings
6
+
7
+ import numpy as np
8
+ import pandas as pd
9
+ from astropy.time import Time
10
+ from rubin_scheduler.data import get_data_dir
11
+
12
+ from rubin_sim.moving_objects import ChebyFits, ChebyValues, Orbits, PyOrbEphemerides
13
+
14
+ ROOT = os.path.abspath(os.path.dirname(__file__))
15
+
16
+
17
+ @unittest.skip("Temporary skip until ephemerides replaced")
18
+ class TestChebyValues(unittest.TestCase):
19
+ def setUp(self):
20
+ self.testdatadir = os.path.join(get_data_dir(), "tests", "orbits_testdata")
21
+ self.scratch_dir = tempfile.mkdtemp(dir=ROOT, prefix="TestChebyValues-")
22
+ self.coeff_file = os.path.join(self.scratch_dir, "test_coeffs")
23
+ self.resid_file = os.path.join(self.scratch_dir, "test_resids")
24
+ self.failed_file = os.path.join(self.scratch_dir, "test_failed")
25
+ self.orbits = Orbits()
26
+ self.orbits.read_orbits(os.path.join(self.testdatadir, "test_orbitsNEO.s3m"), skiprows=1)
27
+ self.pyephems = PyOrbEphemerides()
28
+ self.pyephems.set_orbits(self.orbits)
29
+ self.t_start = self.orbits.orbits.epoch.iloc[0]
30
+ self.interval = 30
31
+ self.n_coeffs = 14
32
+ self.n_decimal = 13
33
+
34
+ self.cheby_fits = ChebyFits(
35
+ self.orbits,
36
+ self.t_start,
37
+ self.interval,
38
+ ngran=64,
39
+ sky_tolerance=2.5,
40
+ n_decimal=self.n_decimal,
41
+ n_coeff_position=self.n_coeffs,
42
+ obscode=807,
43
+ time_scale="TAI",
44
+ )
45
+ self.set_length = 0.5
46
+ self.cheby_fits.calc_segment_length(length=self.set_length)
47
+ self.cheby_fits.calc_segments()
48
+ self.cheby_fits.write(self.coeff_file, self.resid_file, self.failed_file, append=False)
49
+ self.coeff_keys = [
50
+ "obj_id",
51
+ "t_start",
52
+ "t_end",
53
+ "ra",
54
+ "dec",
55
+ "geo_dist",
56
+ "vmag",
57
+ "elongation",
58
+ ]
59
+
60
+ def tearDown(self):
61
+ del self.orbits
62
+ del self.cheby_fits
63
+ if os.path.exists(self.scratch_dir):
64
+ shutil.rmtree(self.scratch_dir)
65
+
66
+ def test_set_coeff(self):
67
+ # Test setting coefficients directly from chebyFits outputs.
68
+ cheby_values = ChebyValues()
69
+ cheby_values.set_coefficients(self.cheby_fits)
70
+ for k in self.coeff_keys:
71
+ self.assertTrue(k in cheby_values.coeffs)
72
+ self.assertTrue(isinstance(cheby_values.coeffs[k], np.ndarray))
73
+ self.assertEqual(len(np.unique(cheby_values.coeffs["obj_id"])), len(self.orbits))
74
+ # This will only be true for carefully selected length/orbit type,
75
+ # where subdivision did not occur.
76
+ # For the test MBAs, a len=1day will work.
77
+ # For the test NEOs, a len=0.25 day will work (with 2.5mas skyTol).
78
+ # self.assertEqual(len(cheby_values.coeffs['tStart']),
79
+ # (self.interval / self.set_length) * len(self.orbits))
80
+ self.assertEqual(len(cheby_values.coeffs["ra"][0]), self.n_coeffs)
81
+ self.assertTrue("meanRA" in cheby_values.coeffs)
82
+ self.assertTrue("meanDec" in cheby_values.coeffs)
83
+
84
+ def test_read_coeffs(self):
85
+ # Test reading the coefficients from disk.
86
+ cheby_values = ChebyValues()
87
+ cheby_values.read_coefficients(self.coeff_file)
88
+ cheby_values2 = ChebyValues()
89
+ cheby_values2.set_coefficients(self.cheby_fits)
90
+ for k in cheby_values.coeffs:
91
+ if k == "obj_id":
92
+ # Can't test strings with np.test.assert_almost_equal.
93
+ np.testing.assert_equal(cheby_values.coeffs[k], cheby_values2.coeffs[k])
94
+ else:
95
+ # All of these will only be accurate to 2 less decimal places
96
+ # than they are print out with in chebyFits. Since vmag,
97
+ # delta and elongation only use 7
98
+ # decimal places, this means we can test to 5 decimal
99
+ # places for those.
100
+ np.testing.assert_allclose(cheby_values.coeffs[k], cheby_values2.coeffs[k], rtol=0, atol=1e-5)
101
+
102
+ def test_get_ephemerides(self):
103
+ # Test that get_ephemerides works and is accurate.
104
+ cheby_values = ChebyValues()
105
+ cheby_values.set_coefficients(self.cheby_fits)
106
+
107
+ # Multiple times, all objects, all within interval.
108
+ tstep = self.interval / 10.0
109
+ time = np.arange(self.t_start, self.t_start + self.interval, tstep)
110
+ # Test for a single time, but all the objects.
111
+ ephemerides = cheby_values.get_ephemerides(time)
112
+ pyephemerides = self.pyephems.generate_ephemerides(
113
+ time, obscode=807, time_scale="TAI", by_object=True
114
+ )
115
+ # Looks like there's some weird hardware dependent issue
116
+ # where cheby_fits is failing to fit some orbits.
117
+
118
+ # RA and Dec should agree to 2.5mas (sky_tolerance above)
119
+ pos_residuals = np.sqrt(
120
+ (ephemerides["ra"] - pyephemerides["ra"]) ** 2
121
+ + ((ephemerides["dec"] - pyephemerides["dec"]) * np.cos(np.radians(ephemerides["dec"]))) ** 2
122
+ )
123
+ pos_residuals *= 3600.0 * 1000.0
124
+ if not np.all(np.isfinite(ephemerides["ra"])):
125
+ warnings.warn("NaN values from ChebyValues.get_ephemerides, skipping some tests")
126
+ else:
127
+ # Let's just look at the max residuals in all quantities.
128
+ for k in ("ra", "dec", "dradt", "ddecdt", "geo_dist"):
129
+ resids = np.abs(ephemerides[k] - pyephemerides[k])
130
+ if k != "geo_dist":
131
+ resids *= 3600.0 * 1000.0
132
+ print("max diff", k, np.max(resids))
133
+ resids = np.abs(ephemerides["elongation"] - pyephemerides["solarelon"])
134
+ print("max diff elongation", np.max(resids))
135
+ resids = np.abs(ephemerides["vmag"] - pyephemerides["magV"])
136
+ print("max diff vmag", np.max(resids))
137
+ self.assertLessEqual(np.nanmax(pos_residuals), 2.5)
138
+ # Test for single time, but for a subset of the objects.
139
+ obj_ids = self.orbits.orbits.obj_id.head(3).values
140
+ ephemerides = cheby_values.get_ephemerides(time, obj_ids)
141
+ self.assertEqual(len(ephemerides["ra"]), 3)
142
+ # Test for time outside of segment range.
143
+ obj_ids = self.orbits.orbits.obj_id.head(3).values
144
+ ephemerides = cheby_values.get_ephemerides(
145
+ self.t_start + self.interval * 2, obj_ids, extrapolate=False
146
+ )
147
+ self.assertTrue(
148
+ np.isnan(ephemerides["ra"][0]),
149
+ msg=f"Expected Nan for out of range ephemeris, got {ephemerides['ra'][0]}",
150
+ )
151
+
152
+
153
+ @unittest.skip("Temporary skip until ephemerides replaced")
154
+ class TestJPLValues(unittest.TestCase):
155
+ # Test the interpolation-generated RA/Dec values against JPL
156
+ # generated RA/Dec values.
157
+ # The resulting errors should be similar to the errors reported
158
+ # from testEphemerides when testing against JPL values.
159
+ def setUp(self):
160
+ # Read orbits.
161
+ self.orbits = Orbits()
162
+ self.jpl_dir = os.path.join(get_data_dir(), "tests", "jpl_testdata")
163
+ self.orbits.read_orbits(os.path.join(self.jpl_dir, "S0_n747.des"), skiprows=1)
164
+ # Read JPL ephems.
165
+ self.jpl = pd.read_table(os.path.join(self.jpl_dir, "807_n747.txt"), sep=r"\s+")
166
+ self.jpl["obj_id"] = self.jpl["objId"]
167
+ # Add times in TAI and UTC, because.
168
+ t = Time(self.jpl["epoch_mjd"], format="mjd", scale="utc")
169
+ self.jpl["mjdTAI"] = t.tai.mjd
170
+ self.jpl["mjdUTC"] = t.utc.mjd
171
+ self.jpl = self.jpl.to_records(index=False)
172
+ # Generate interpolation coefficients for the time period
173
+ # in the JPL catalog.
174
+ self.scratch_dir = tempfile.mkdtemp(dir=ROOT, prefix="TestJPLValues-")
175
+ self.coeff_file = os.path.join(self.scratch_dir, "test_coeffs")
176
+ self.resid_file = os.path.join(self.scratch_dir, "test_resids")
177
+ self.failed_file = os.path.join(self.scratch_dir, "test_failed")
178
+ t_start = self.jpl["mjdTAI"].min() - 0.2
179
+ t_end = self.jpl["mjdTAI"].max() + 0.2 - self.jpl["mjdTAI"].min()
180
+ self.cheby_fits = ChebyFits(
181
+ self.orbits,
182
+ t_start,
183
+ t_end,
184
+ ngran=64,
185
+ sky_tolerance=2.5,
186
+ n_decimal=14,
187
+ obscode=807,
188
+ )
189
+ self.cheby_fits.calc_segment_length()
190
+ self.cheby_fits.calc_segments()
191
+
192
+ self.coeff_keys = [
193
+ "obj_id",
194
+ "t_start",
195
+ "t_end",
196
+ "ra",
197
+ "dec",
198
+ "geo_dist",
199
+ "vmag",
200
+ "elongation",
201
+ ]
202
+ self.cheby_values = ChebyValues()
203
+ self.cheby_values.set_coefficients(self.cheby_fits)
204
+
205
+ def tearDown(self):
206
+ del self.orbits
207
+ del self.jpl
208
+ if os.path.exists(self.scratch_dir):
209
+ shutil.rmtree(self.scratch_dir)
210
+
211
+ def test_ra_dec(self):
212
+ # We won't compare Vmag, because this also needs
213
+ # information on trailing losses.
214
+ times = np.unique(self.jpl["mjdTAI"])
215
+ delta_ra = np.zeros(len(times), float)
216
+ delta_dec = np.zeros(len(times), float)
217
+ for i, t in enumerate(times):
218
+ # Find the JPL obj_ids visible at this time.
219
+ j = self.jpl[np.where(self.jpl["mjdTAI"] == t)]
220
+ ephs = self.cheby_values.get_ephemerides(t, obj_ids=j["obj_id"])
221
+ ephorder = np.argsort(ephs["obj_id"])
222
+ # Sometimes I've had to reorder both, sometimes just the ephs. ??
223
+ jorder = np.argsort(j["obj_id"])
224
+ jorder = np.arange(0, len(jorder))
225
+ d_ra = np.abs(ephs["ra"][ephorder][:, 0] - j["ra_deg"][jorder]) * 3600.0 * 1000.0
226
+ d_dec = np.abs(ephs["dec"][ephorder][:, 0] - j["dec_deg"][jorder]) * 3600.0 * 1000.0
227
+ delta_ra[i] = d_ra.max()
228
+ delta_dec[i] = d_dec.max()
229
+ # Should be (given OOrb direct prediction):
230
+ # Much of the time we're closer than 1mas, but there are a
231
+ # few which hit higher values.
232
+ # This is consistent with the errors/values reported by oorb
233
+ # directly in testEphemerides.
234
+
235
+ # # XXX--units?
236
+ print("max JPL errors", delta_ra.max(), delta_dec.max())
237
+ print("std of JPL errors", np.std(delta_ra), np.std(delta_dec))
238
+ self.assertLess(np.max(delta_ra), 25)
239
+ self.assertLess(np.max(delta_dec), 25)
240
+ self.assertLess(np.std(delta_ra), 3)
241
+ self.assertLess(np.std(delta_dec), 3)
242
+
243
+
244
+ if __name__ == "__main__":
245
+ unittest.main()