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,221 @@
1
+ __all__ = ("StackerRegistry", "BaseStacker")
2
+
3
+ import inspect
4
+ import warnings
5
+
6
+ import numpy as np
7
+
8
+
9
+ class StackerRegistry(type):
10
+ """
11
+ Meta class for Stackers, to build a registry of stacker classes.
12
+ """
13
+
14
+ def __init__(cls, name, bases, dict):
15
+ super(StackerRegistry, cls).__init__(name, bases, dict)
16
+ if not hasattr(cls, "registry"):
17
+ cls.registry = {}
18
+ if not hasattr(cls, "source_dict"):
19
+ cls.source_dict = {}
20
+ modname = inspect.getmodule(cls).__name__
21
+ if modname.startswith("rubin_sim.maf.stackers"):
22
+ modname = ""
23
+ else:
24
+ if len(modname.split(".")) > 1:
25
+ modname = ".".join(modname.split(".")[:-1]) + "."
26
+ else:
27
+ modname = modname + "."
28
+ stackername = modname + name
29
+ if stackername in cls.registry:
30
+ raise Exception(
31
+ "Redefining stacker %s! (there are >1 stackers with the same name)" % (stackername)
32
+ )
33
+ if stackername != "BaseStacker":
34
+ cls.registry[stackername] = cls
35
+ cols_added = cls.cols_added
36
+ for col in cols_added:
37
+ cls.source_dict[col] = cls
38
+
39
+ def get_class(cls, stackername):
40
+ return cls.registry[stackername]
41
+
42
+ def help(cls, doc=False):
43
+ for stackername in sorted(cls.registry):
44
+ if not doc:
45
+ print(stackername)
46
+ if doc:
47
+ print("---- ", stackername, " ----")
48
+ print(cls.registry[stackername].__doc__)
49
+ stacker = cls.registry[stackername]()
50
+ print(" Columns added to SimData: ", ",".join(stacker.cols_added))
51
+ print(" Default columns required: ", ",".join(stacker.cols_req))
52
+
53
+
54
+ class BaseStacker(metaclass=StackerRegistry):
55
+ """Base MAF Stacker.
56
+
57
+ Stackers add columns generated at run-time to the simdata array.
58
+ """
59
+
60
+ # List of the names of the columns generated by the Stacker.
61
+ cols_added = []
62
+
63
+ def __init__(self):
64
+ """
65
+ Instantiate the stacker.
66
+ This method should be overriden by the user.
67
+ This serves to define the API required by MAF.
68
+ """
69
+ # Add the list of new columns generated by the stacker
70
+ # as class attributes (colsAdded - above).
71
+
72
+ # List of the names of the columns required from the database
73
+ # (to generate the Stacker columns).
74
+ self.cols_req = []
75
+ # Optional: specify the new column types.
76
+ self.cols_added_dtypes = None
77
+ # Optional: provide a list of units for the columns
78
+ # defined in colsAdded.
79
+ self.units = [None]
80
+
81
+ def __hash__(self):
82
+ return None
83
+
84
+ def __eq__(self, other_stacker):
85
+ """
86
+ Evaluate if two stackers are equivalent.
87
+
88
+ This method is required to determine if metric_bundles may be
89
+ evaluated at the same time, on the same data.
90
+ """
91
+ # If the class names are different, they are not 'the same'.
92
+ if self.__class__.__name__ != other_stacker.__class__.__name__:
93
+ return False
94
+ # Otherwise, this is the same stacker class,
95
+ # but may be instantiated differently.
96
+ # We have to delve a little further,
97
+ # and compare the kwargs & attributes for each stacker.
98
+ state_now = dir(self)
99
+ for key in state_now:
100
+ if not key.startswith("_") and key != "registry" and key != "run" and key != "next":
101
+ if not hasattr(other_stacker, key):
102
+ return False
103
+ # If the attribute is from numpy, assume it's an array
104
+ # and test it
105
+ if type(getattr(self, key)).__module__ == np.__name__:
106
+ if not np.array_equal(getattr(self, key), getattr(other_stacker, key)):
107
+ return False
108
+ else:
109
+ if getattr(self, key) != getattr(other_stacker, key):
110
+ return False
111
+ return True
112
+
113
+ def __ne__(self, other_stacker):
114
+ """
115
+ Evaluate if two stackers are not equal.
116
+ """
117
+ if self == other_stacker:
118
+ return False
119
+ else:
120
+ return True
121
+
122
+ def _add_stacker_cols(self, sim_data):
123
+ """
124
+ Add the new Stacker columns to the sim_data array.
125
+ If columns already present in sim_data,
126
+ just allows 'run' method to overwrite.
127
+ Returns sim_data array with these columns added
128
+ (so 'run' method can set their values).
129
+ """
130
+ if not hasattr(self, "cols_added_dtypes") or self.cols_added_dtypes is None:
131
+ self.cols_added_dtypes = [float for col in self.cols_added]
132
+ # Create description of new recarray.
133
+ newdtype = sim_data.dtype.descr
134
+ cols_present = [False] * len(self.cols_added)
135
+ for i, (col, dtype) in enumerate(zip(self.cols_added, self.cols_added_dtypes)):
136
+ if col in sim_data.dtype.names:
137
+ if sim_data[col][0] is not None:
138
+ cols_present[i] = True
139
+ warnings.warn(
140
+ "Warning - column %s already present in sim_data, may be overwritten "
141
+ "(depending on stacker)." % (col)
142
+ )
143
+ else:
144
+ newdtype += [(col, dtype)]
145
+ new_data = np.empty(sim_data.shape, dtype=newdtype)
146
+ # Add references to old data.
147
+ for col in sim_data.dtype.names:
148
+ new_data[col] = sim_data[col]
149
+ # Were all columns present and populated with something not None?
150
+ # If so, then consider 'all there'.
151
+ if sum(cols_present) == len(self.cols_added):
152
+ cols_present = True
153
+ else:
154
+ cols_present = False
155
+ return new_data, cols_present
156
+
157
+ def run(self, sim_data, override=False):
158
+ """
159
+ Run the stacker, adding new columns.
160
+
161
+ Parameters
162
+ ----------
163
+ sim_data : `np.ndarray`, (N, M)
164
+ The data to be used to evaluate metrics.
165
+ override : `bool`, optional
166
+ If True, recalculate new (stacker) columns even if present.
167
+ If False, calculates stacker columns only if they are not present.
168
+
169
+
170
+ Returns
171
+ -------
172
+ sim_data : `np.ndarray`, (N, MM)
173
+ The input data, plus additional stacker columns.
174
+ """
175
+ # Add new columns
176
+ if len(sim_data) == 0:
177
+ return sim_data
178
+ sim_data, cols_present = self._add_stacker_cols(sim_data)
179
+ # If override is set, it means go ahead and recalculate stacker values.
180
+ if override:
181
+ cols_present = False
182
+ # Run the method to calculate/add new data.
183
+ try:
184
+ return self._run(sim_data, cols_present)
185
+ except TypeError:
186
+ warnings.warn(
187
+ "Please update the stacker %s so that the _run method matches the current API. "
188
+ "This will give you the option to skip re-running stackers if the columns are "
189
+ "already present." % (self.__class__.__name__)
190
+ )
191
+ return self._run(sim_data)
192
+
193
+ def _run(self, sim_data, cols_present=False):
194
+ """Do the work to add the new columns. This method should be overriden
195
+ in subclasses.
196
+
197
+ Parameters
198
+ ----------
199
+ sim_data: `np.ndarray`, (N, M)
200
+ The observation data, provided by the MAF framework.
201
+ cols_present: `bool`, optional
202
+ Flag to indicate what to do with the columns already present in
203
+ the data. This will also be provided by the MAF framework --
204
+ but your _run method can use the value. If it is 'True' and you
205
+ do trust the existing value, the _run method can simply
206
+ return sim_data without additional calculations.
207
+
208
+ Returns
209
+ -------
210
+ sim_data : `np.ndarray`, (N, MM)
211
+ The simdata, with the columns added or updated
212
+ (or simply already present).
213
+ """
214
+ # By moving the calculation of these columns to a separate method,
215
+ # we add the possibility of using stackers with pandas dataframes.
216
+ # The _addStackerCols method won't work with dataframes, but the
217
+ # _run methods are quite likely to (depending on their details),
218
+ # as they are just populating columns.
219
+ raise NotImplementedError(
220
+ "Not Implemented: " "the child stackers should implement their own _run methods"
221
+ )
@@ -0,0 +1,224 @@
1
+ __all__ = ("ra_dec2_alt_az", "GalacticStacker", "EclipticStacker", "HealpixStacker")
2
+
3
+ import healpy as hp
4
+ import numpy as np
5
+ from astropy import units as u
6
+ from astropy.coordinates import SkyCoord, get_sun
7
+ from astropy.time import Time
8
+ from rubin_scheduler.utils import calc_lmst
9
+
10
+ from .base_stacker import BaseStacker
11
+
12
+
13
+ def wrap_ra(ra):
14
+ """
15
+ Wrap only RA values into 0-2pi (using mod).
16
+
17
+ Parameters
18
+ ----------
19
+ ra : numpy.ndarray
20
+ RA in radians
21
+
22
+ Returns
23
+ -------
24
+ numpy.ndarray
25
+ Wrapped RA values, in radians.
26
+ """
27
+ ra = ra % (2.0 * np.pi)
28
+ return ra
29
+
30
+
31
+ def ra_dec2_alt_az(ra, dec, lat, lon, mjd, altonly=False):
32
+ """Convert RA/Dec (and telescope site lat/lon) to alt/az.
33
+
34
+ This uses simple equations and ignores aberation, precession, nutation.
35
+
36
+ Parameters
37
+ ----------
38
+ ra : `np.ndarray`, (N,)
39
+ RA, in radians.
40
+ dec : `np.ndarray`, (N,)
41
+ Dec, in radians. Must be same length as `ra`.
42
+ lat : `float`
43
+ Latitude of the observatory in radians.
44
+ lon : `float`
45
+ Longitude of the observatory in radians.
46
+ mjd : `float`
47
+ Modified Julian Date.
48
+ altonly : `bool`, optional
49
+ Calculate altitude only.
50
+
51
+ Returns
52
+ -------
53
+ alt : `np.ndarray`, (N,)
54
+ Altitude, same length as `ra` and `dec`. Radians.
55
+ az : `np.ndarray`, (N,)
56
+ Azimuth, same length as `ra` and `dec`. Radians.
57
+ """
58
+ lmst = calc_lmst(mjd, lon)
59
+ lmst = lmst / 12.0 * np.pi # convert to rad
60
+ ha = lmst - ra
61
+ sindec = np.sin(dec)
62
+ sinlat = np.sin(lat)
63
+ coslat = np.cos(lat)
64
+ sinalt = sindec * sinlat + np.cos(dec) * coslat * np.cos(ha)
65
+ # make sure sinalt is in the expected range.
66
+ sinalt = np.where(sinalt < -1, -1, sinalt)
67
+ sinalt = np.where(sinalt > 1, 1, sinalt)
68
+ alt = np.arcsin(sinalt)
69
+ if altonly:
70
+ az = None
71
+ else:
72
+ cosaz = (sindec - np.sin(alt) * sinlat) / (np.cos(alt) * coslat)
73
+ cosaz = np.where(cosaz < -1, -1, cosaz)
74
+ cosaz = np.where(cosaz > 1, 1, cosaz)
75
+ az = np.arccos(cosaz)
76
+ signflip = np.where(np.sin(ha) > 0)
77
+ az[signflip] = 2.0 * np.pi - az[signflip]
78
+ return alt, az
79
+
80
+
81
+ class GalacticStacker(BaseStacker):
82
+ """Add the galactic coordinates of each RA/Dec pointing: gall, galb
83
+
84
+ Parameters
85
+ ----------
86
+ ra_col : str, optional
87
+ Name of the RA column. Default fieldRA.
88
+ dec_col : str, optional
89
+ Name of the Dec column. Default fieldDec.
90
+ """
91
+
92
+ cols_added = ["gall", "galb"]
93
+
94
+ def __init__(self, ra_col="fieldRA", dec_col="fieldDec", degrees=True):
95
+ self.cols_req = [ra_col, dec_col]
96
+ self.ra_col = ra_col
97
+ self.dec_col = dec_col
98
+ self.degrees = degrees
99
+ if self.degrees:
100
+ self.units = ["degrees", "degrees"]
101
+ else:
102
+ self.units = ["radians", "radians"]
103
+
104
+ def _run(self, sim_data, cols_present=False):
105
+ # raCol and DecCol in radians, gall/b in radians.
106
+ if cols_present:
107
+ # Column already present in data;
108
+ # assume it is correct and does not need recalculating.
109
+ return sim_data
110
+ if self.degrees:
111
+ c = SkyCoord(ra=sim_data[self.ra_col] * u.deg, dec=sim_data[self.dec_col] * u.deg).transform_to(
112
+ "galactic"
113
+ )
114
+ else:
115
+ c = SkyCoord(ra=sim_data[self.ra_col] * u.rad, dec=sim_data[self.dec_col] * u.rad).transform_to(
116
+ "galactic"
117
+ )
118
+ sim_data["gall"] = c.l.rad
119
+ sim_data["galb"] = c.b.rad
120
+ return sim_data
121
+
122
+
123
+ class EclipticStacker(BaseStacker):
124
+ """Add the ecliptic coordinates of each RA/Dec pointing:
125
+ eclipLat, eclipLon
126
+
127
+ Optionally subtract off the sun's ecliptic longitude and wrap.
128
+
129
+ Parameters
130
+ ----------
131
+ mjd_col : str, optional
132
+ Name of the MJD column. Default expMJD.
133
+ ra_col : str, optional
134
+ Name of the RA column. Default fieldRA.
135
+ dec_col : str, optional
136
+ Name of the Dec column. Default fieldDec.
137
+ subtract_sun_lon : bool, optional
138
+ Flag to subtract the sun's ecliptic longitude. Default False.
139
+ """
140
+
141
+ cols_added = ["eclipLat", "eclipLon"]
142
+
143
+ def __init__(
144
+ self,
145
+ mjd_col="observationStartMJD",
146
+ ra_col="fieldRA",
147
+ dec_col="fieldDec",
148
+ degrees=True,
149
+ subtract_sun_lon=False,
150
+ ):
151
+ self.cols_req = [mjd_col, ra_col, dec_col]
152
+ self.subtract_sun_lon = subtract_sun_lon
153
+ self.degrees = degrees
154
+ if self.degrees:
155
+ self.units = ["degrees", "degrees"]
156
+ else:
157
+ self.units = ["radians", "radians"]
158
+ self.mjd_col = mjd_col
159
+ self.ra_col = ra_col
160
+ self.dec_col = dec_col
161
+
162
+ def _run(self, sim_data, cols_present=False):
163
+ if cols_present:
164
+ # Column already present in data;
165
+ # assume it is correct and does not need recalculating.
166
+ return sim_data
167
+ for i in np.arange(sim_data.size):
168
+ if self.degrees:
169
+ coord = SkyCoord(
170
+ ra=sim_data[self.ra_col] * u.degree,
171
+ dec=sim_data[self.dec_col] * u.degree,
172
+ )
173
+ else:
174
+ coord = SkyCoord(ra=sim_data[self.ra_col] * u.rad, dec=sim_data[self.dec_col] * u.rad)
175
+ coord_ecl = coord.geocentricmeanecliptic
176
+ sim_data["eclipLat"] = coord_ecl.lat.rad
177
+
178
+ if self.subtract_sun_lon:
179
+ times = Time(sim_data[self.mjd_col])
180
+ sun = get_sun(times)
181
+ sun_ecl = sun.geocentricmeanecliptic
182
+ lon = wrap_ra(coord_ecl.lon.rad - sun_ecl.lon.rad)
183
+ sim_data["eclipLon"] = lon
184
+ else:
185
+ sim_data["eclipLon"] = coord_ecl.lon.rad
186
+ if self.degrees:
187
+ sim_data["eclipLon"] = np.degrees(sim_data["eclipLon"])
188
+ sim_data["eclipLat"] = np.degrees(sim_data["eclipLat"])
189
+ return sim_data
190
+
191
+
192
+ class HealpixStacker(BaseStacker):
193
+ """Add healpix id
194
+
195
+ Parameters
196
+ ----------
197
+ ra_col : str, optional
198
+ Name of the RA column. Default fieldRA.
199
+ dec_col : str, optional
200
+ Name of the Dec column. Default fieldDec.
201
+ nside : int
202
+ nside healpix to use. Default to 128.
203
+ """
204
+
205
+ cols_added = ["ring_healpix", "nest_healpix"]
206
+
207
+ def __init__(self, ra_col: str = "fieldRA", dec_col: str = "fieldDec", nside: int = 128):
208
+ self.cols_req = [ra_col, dec_col]
209
+ self.ra_col = ra_col
210
+ self.dec_col = dec_col
211
+ self.nside = nside
212
+ self.units = [f"healpix (ring, nside={nside})", f"healpix (nest, nside={nside})"]
213
+
214
+ def _run(self, sim_data, cols_present=False):
215
+ if cols_present:
216
+ # Column already present in data;
217
+ # assume it is correct and does not need recalculating.
218
+ return sim_data
219
+
220
+ ra = sim_data[self.ra_col]
221
+ decl = sim_data[self.dec_col]
222
+ sim_data["ring_healpix"] = hp.ang2pix(self.nside, ra, decl, nest=False, lonlat=True)
223
+ sim_data["nest_healpix"] = hp.ang2pix(self.nside, ra, decl, nest=True, lonlat=True)
224
+ return sim_data
@@ -0,0 +1,192 @@
1
+ __all__ = (
2
+ "ObservationStartDatetime64Stacker",
3
+ "ObservationStartTimestampStacker",
4
+ "DayObsStacker",
5
+ "DayObsMJDStacker",
6
+ "DayObsISOStacker",
7
+ )
8
+
9
+ import numpy as np
10
+ import pandas as pd
11
+ from astropy.time import Time
12
+
13
+ from .base_stacker import BaseStacker
14
+
15
+
16
+ class ObservationStartDatetime64Stacker(BaseStacker):
17
+ """Add the observation start time as a numpy.datetime64."""
18
+
19
+ cols_added = ["observationStartDatetime64"]
20
+
21
+ def __init__(
22
+ self,
23
+ mjd_col="observationStartMJD",
24
+ ):
25
+ self.mjd_col = mjd_col
26
+ self.cols_req = [self.mjd_col]
27
+ self.units = [None]
28
+ self.cols_added_dtypes = ["datetime64[ns]"]
29
+
30
+ def _run(self, sim_data, cols_present=False):
31
+ if cols_present:
32
+ # Column already present in data; assume it is correct and does not
33
+ # need recalculating.
34
+ return sim_data
35
+
36
+ sim_data["observationStartDatetime64"] = Time(sim_data[self.mjd_col], format="mjd").datetime64
37
+
38
+ return sim_data
39
+
40
+
41
+ class ObservationStartTimestampStacker(BaseStacker):
42
+ """Add the observation start time as a pandas.Timestamp."""
43
+
44
+ cols_added = ["start_timestamp"]
45
+
46
+ def __init__(
47
+ self,
48
+ mjd_col="observationStartMJD",
49
+ ):
50
+ self.mjd_col = mjd_col
51
+ self.cols_req = [self.mjd_col]
52
+ self.units = [None]
53
+ self.cols_added_dtypes = ["O"]
54
+
55
+ def run(self, sim_data, override=False):
56
+ # Override the run from the base class, not _run,
57
+ # because the implementation
58
+ # of _add_stackers_cols in run in the base closs
59
+ # clobbers the type for the new column,
60
+ # which we really need.
61
+
62
+ visits = sim_data if isinstance(sim_data, pd.DataFrame) else pd.DataFrame(sim_data)
63
+
64
+ if "start_timestamp" in visits.columns and not override:
65
+ return sim_data
66
+
67
+ if len(visits[self.mjd_col]) > 0:
68
+ visits["start_timestamp"] = pd.to_datetime(
69
+ visits[self.mjd_col] + 2400000.5, origin="julian", unit="D", utc=True
70
+ )
71
+ else:
72
+ # If we are passed an empty series, be sure to return add an empty
73
+ # series of the correct type back.
74
+ # This is handy if the result is being passed to bokeh
75
+ # for plotting.
76
+ visits["start_timestamp"] = pd.to_datetime(2460000.5, origin="julian", unit="D", utc=True)
77
+
78
+ match sim_data:
79
+ case pd.DataFrame():
80
+ return visits
81
+ case dict():
82
+ return visits.to_dict()
83
+ case _:
84
+ return visits.to_records(index=False)
85
+
86
+
87
+ def _compute_day_obs_mjd(mjd):
88
+ day_obs_mjd = np.floor(mjd - 0.5).astype("int")
89
+ return day_obs_mjd
90
+
91
+
92
+ def _compute_day_obs_astropy_time(mjd):
93
+ day_obs_time = Time(_compute_day_obs_mjd(mjd), format="mjd")
94
+ return day_obs_time
95
+
96
+
97
+ def _compute_day_obs_iso8601(mjd):
98
+ iso_times = _compute_day_obs_astropy_time(mjd).iso
99
+
100
+ # Work both for mjd as a scalar and a numpy array
101
+ if isinstance(iso_times, str):
102
+ day_obs_iso = iso_times[:10]
103
+ else:
104
+ day_obs_iso = np.array([d[:10] for d in iso_times])
105
+
106
+ return day_obs_iso
107
+
108
+
109
+ def _compute_day_obs_int(mjd):
110
+ day_obs_int = np.array([d.replace("-", "") for d in _compute_day_obs_iso8601(mjd)])
111
+
112
+ return day_obs_int
113
+
114
+
115
+ class DayObsStacker(BaseStacker):
116
+ """Add dayObs as, as defined by SITCOMTN-32.
117
+
118
+ Parameters
119
+ ----------
120
+ mjd_col : `str`
121
+ The column with the observatin start MJD.
122
+ """
123
+
124
+ cols_added = ["dayObs"]
125
+
126
+ def __init__(self, mjd_col="observationStartMJD"):
127
+ self.mjd_col = mjd_col
128
+ self.cols_req = [self.mjd_col]
129
+ self.units = ["days"]
130
+ self.cols_added_dtypes = [int]
131
+
132
+ def _run(self, sim_data, cols_present=False):
133
+ if cols_present:
134
+ # Column already present in data; assume it is correct and does not
135
+ # need recalculating.
136
+ return sim_data
137
+
138
+ sim_data[self.cols_added[0]] = _compute_day_obs_int(sim_data[self.mjd_col])
139
+ return sim_data
140
+
141
+
142
+ class DayObsMJDStacker(BaseStacker):
143
+ """Add dayObs defined by SITCOMTN-32, as an MJD.
144
+
145
+ Parameters
146
+ ----------
147
+ mjd_col : `str`
148
+ The column with the observatin start MJD.
149
+ """
150
+
151
+ cols_added = ["day_obs_mjd"]
152
+
153
+ def __init__(self, mjd_col="observationStartMJD"):
154
+ self.mjd_col = mjd_col
155
+ self.cols_req = [self.mjd_col]
156
+ self.units = ["days"]
157
+ self.cols_added_dtypes = [int]
158
+
159
+ def _run(self, sim_data, cols_present=False):
160
+ if cols_present:
161
+ # Column already present in data; assume it is correct and does not
162
+ # need recalculating.
163
+ return sim_data
164
+
165
+ sim_data[self.cols_added[0]] = _compute_day_obs_mjd(sim_data[self.mjd_col])
166
+ return sim_data
167
+
168
+
169
+ class DayObsISOStacker(BaseStacker):
170
+ """Add dayObs as defined by SITCOMTN-32, in ISO 8601 format.
171
+
172
+ Parameters
173
+ ----------
174
+ mjd_col : `str`
175
+ The column with the observatin start MJD."""
176
+
177
+ cols_added = ["day_obs_iso8601"]
178
+
179
+ def __init__(self, mjd_col="observationStartMJD"):
180
+ self.mjd_col = mjd_col
181
+ self.cols_req = [self.mjd_col]
182
+ self.units = [None]
183
+ self.cols_added_dtypes = [(str, 10)]
184
+
185
+ def _run(self, sim_data, cols_present=False):
186
+ if cols_present:
187
+ # Column already present in data; assume it is correct and does not
188
+ # need recalculating.
189
+ return sim_data
190
+
191
+ sim_data[self.cols_added[0]] = _compute_day_obs_iso8601(sim_data[self.mjd_col])
192
+ return sim_data