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.
- batch/compile_prenight_metadata_cache.sh +34 -0
- batch/run_auxtel_prenight_sims.sh +163 -0
- batch/run_prenight_sims.sh +239 -0
- docs/.gitignore +3 -0
- docs/Makefile +32 -0
- docs/api.rst +25 -0
- docs/conf.py +8 -0
- docs/data-api.rst +12 -0
- docs/data-download.rst +70 -0
- docs/developer.rst +14 -0
- docs/documenteer.toml +11 -0
- docs/index.rst +22 -0
- docs/installation.rst +76 -0
- docs/introduction.rst +37 -0
- docs/maf-api-batches.rst +12 -0
- docs/maf-api-db.rst +12 -0
- docs/maf-api-maf-contrib.rst +12 -0
- docs/maf-api-maps.rst +12 -0
- docs/maf-api-metricbundles.rst +12 -0
- docs/maf-api-metrics.rst +12 -0
- docs/maf-api-plots.rst +12 -0
- docs/maf-api-run-comparison.rst +12 -0
- docs/maf-api-slicers.rst +12 -0
- docs/maf-api-stackers.rst +12 -0
- docs/maf-api-utils.rst +12 -0
- docs/maf-api.rst +22 -0
- docs/maf.rst +60 -0
- docs/metric_list.py +49 -0
- docs/moving-objects-api.rst +12 -0
- docs/moving-objects.rst +22 -0
- docs/phot-utils-api.rst +12 -0
- docs/phot-utils.rst +11 -0
- docs/prenight.rst +117 -0
- docs/protoarchive.rst +276 -0
- docs/satellite-constellations-api.rst +12 -0
- docs/satellite-constellations.rst +13 -0
- docs/selfcal-api.rst +12 -0
- docs/selfcal.rst +15 -0
- docs/sim-archive-api.rst +12 -0
- docs/skybrightness-api.rst +12 -0
- docs/skybrightness.rst +23 -0
- docs/user-guide.rst +28 -0
- docs/vseqarchive-architecture.rst +438 -0
- docs/vseqarchive-setup.rst +238 -0
- docs/vseqarchive.rst +225 -0
- rubin_sim/__init__.py +7 -0
- rubin_sim/data/__init__.py +1 -0
- rubin_sim/data/rs_download_data.py +155 -0
- rubin_sim/maf/__init__.py +34 -0
- rubin_sim/maf/batches/__init__.py +18 -0
- rubin_sim/maf/batches/altaz_batch.py +161 -0
- rubin_sim/maf/batches/col_map_dict.py +274 -0
- rubin_sim/maf/batches/common.py +388 -0
- rubin_sim/maf/batches/ddf_batch.py +728 -0
- rubin_sim/maf/batches/filterchange_batch.py +182 -0
- rubin_sim/maf/batches/glance_batch.py +591 -0
- rubin_sim/maf/batches/hourglass_batch.py +79 -0
- rubin_sim/maf/batches/info_batch.py +114 -0
- rubin_sim/maf/batches/metadata_batch.py +558 -0
- rubin_sim/maf/batches/moving_objects_batch.py +1587 -0
- rubin_sim/maf/batches/openshutter_batch.py +100 -0
- rubin_sim/maf/batches/radar_limited.py +1100 -0
- rubin_sim/maf/batches/science_radar_batch.py +1910 -0
- rubin_sim/maf/batches/skycoverage.py +155 -0
- rubin_sim/maf/batches/slew_batch.py +146 -0
- rubin_sim/maf/batches/srd_batch.py +637 -0
- rubin_sim/maf/batches/time_batch.py +757 -0
- rubin_sim/maf/batches/time_sci_batch.py +105 -0
- rubin_sim/maf/batches/visitdepth_batch.py +485 -0
- rubin_sim/maf/db/__init__.py +2 -0
- rubin_sim/maf/db/add_run.py +34 -0
- rubin_sim/maf/db/results_db.py +1074 -0
- rubin_sim/maf/db/tracking_db.py +332 -0
- rubin_sim/maf/ddf_dir.py +53 -0
- rubin_sim/maf/generate_ss.py +218 -0
- rubin_sim/maf/glance_dir.py +58 -0
- rubin_sim/maf/maf_contrib/__init__.py +25 -0
- rubin_sim/maf/maf_contrib/calculate_lsst_field_visibility_astropy.py +170 -0
- rubin_sim/maf/maf_contrib/depth_limited_num_gal_metric.py +109 -0
- rubin_sim/maf/maf_contrib/example_new_metrics.py +40 -0
- rubin_sim/maf/maf_contrib/filter_pair_t_gaps_metric.py +208 -0
- rubin_sim/maf/maf_contrib/grb_transient_metric.py +249 -0
- rubin_sim/maf/maf_contrib/gw170817_det_metric.py +72 -0
- rubin_sim/maf/maf_contrib/intervals_between_obs_metric.py +68 -0
- rubin_sim/maf/maf_contrib/kne_metrics.py +473 -0
- rubin_sim/maf/maf_contrib/lss_metrics.py +45 -0
- rubin_sim/maf/maf_contrib/lss_obs_strategy/__init__.py +3 -0
- rubin_sim/maf/maf_contrib/lss_obs_strategy/constants_for_pipeline.py +73 -0
- rubin_sim/maf/maf_contrib/lss_obs_strategy/galaxy_counts_metric_extended.py +205 -0
- rubin_sim/maf/maf_contrib/lss_obs_strategy/galaxy_counts_with_pixel_calibration.py +171 -0
- rubin_sim/maf/maf_contrib/lv_dwarfs/__init__.py +1 -0
- rubin_sim/maf/maf_contrib/lv_dwarfs/lv_dwarfs_metrics.py +388 -0
- rubin_sim/maf/maf_contrib/microlensing_metric.py +593 -0
- rubin_sim/maf/maf_contrib/num_obs_in_survey_time_overlap_metric.py +43 -0
- rubin_sim/maf/maf_contrib/periodic_metric.py +51 -0
- rubin_sim/maf/maf_contrib/periodic_star_metric.py +186 -0
- rubin_sim/maf/maf_contrib/periodic_star_modulation_metric.py +236 -0
- rubin_sim/maf/maf_contrib/presto_color_kne_pop_metric.py +441 -0
- rubin_sim/maf/maf_contrib/selfcal_uniformity_metric.py +171 -0
- rubin_sim/maf/maf_contrib/star_count_mass_metric.py +64 -0
- rubin_sim/maf/maf_contrib/star_count_metric.py +56 -0
- rubin_sim/maf/maf_contrib/star_counts/__init__.py +8 -0
- rubin_sim/maf/maf_contrib/star_counts/abs_mag.py +324 -0
- rubin_sim/maf/maf_contrib/star_counts/coords.py +99 -0
- rubin_sim/maf/maf_contrib/star_counts/readme.txt +1 -0
- rubin_sim/maf/maf_contrib/star_counts/spec_type.py +91 -0
- rubin_sim/maf/maf_contrib/star_counts/starcount.py +30 -0
- rubin_sim/maf/maf_contrib/star_counts/starcount_bymass.py +93 -0
- rubin_sim/maf/maf_contrib/star_counts/stellardensity.py +59 -0
- rubin_sim/maf/maf_contrib/static_probes_fom_summary_metric.py +386 -0
- rubin_sim/maf/maf_contrib/tdes_pop_metric.py +362 -0
- rubin_sim/maf/maf_contrib/transient_ascii_sed_metric.py +652 -0
- rubin_sim/maf/maf_contrib/triplet_metric.py +156 -0
- rubin_sim/maf/maf_contrib/var_depth_metric.py +157 -0
- rubin_sim/maf/maf_contrib/xrb_metrics.py +523 -0
- rubin_sim/maf/maf_contrib/young_stellar_objects_metric.py +200 -0
- rubin_sim/maf/maf_night_report.py +200 -0
- rubin_sim/maf/make_fbs_tracking_db.py +90 -0
- rubin_sim/maf/maps/__init__.py +8 -0
- rubin_sim/maf/maps/base_map.py +72 -0
- rubin_sim/maf/maps/create_gaia_density_map.py +158 -0
- rubin_sim/maf/maps/dust_map.py +66 -0
- rubin_sim/maf/maps/dust_map_3d.py +190 -0
- rubin_sim/maf/maps/ebv_3d_hp.py +170 -0
- rubin_sim/maf/maps/ebv_hp.py +64 -0
- rubin_sim/maf/maps/gal_coords_map.py +22 -0
- rubin_sim/maf/maps/galactic_plane_priority_maps.py +210 -0
- rubin_sim/maf/maps/stellar_density_map.py +73 -0
- rubin_sim/maf/maps/trilegal_map.py +82 -0
- rubin_sim/maf/metadata_dir.py +90 -0
- rubin_sim/maf/metric_bundles/__init__.py +3 -0
- rubin_sim/maf/metric_bundles/metric_bundle.py +816 -0
- rubin_sim/maf/metric_bundles/metric_bundle_group.py +834 -0
- rubin_sim/maf/metric_bundles/mo_metric_bundle.py +646 -0
- rubin_sim/maf/metrics/__init__.py +52 -0
- rubin_sim/maf/metrics/agn_time_lag_metric.py +118 -0
- rubin_sim/maf/metrics/agnstructure.py +141 -0
- rubin_sim/maf/metrics/area_summary_metrics.py +120 -0
- rubin_sim/maf/metrics/base_metric.py +215 -0
- rubin_sim/maf/metrics/brown_dwarf_metric.py +162 -0
- rubin_sim/maf/metrics/cadence_metrics.py +400 -0
- rubin_sim/maf/metrics/calibration_metrics.py +618 -0
- rubin_sim/maf/metrics/chip_vendor_metric.py +43 -0
- rubin_sim/maf/metrics/color_slope_metrics.py +189 -0
- rubin_sim/maf/metrics/cosmology_summary_metrics.py +1212 -0
- rubin_sim/maf/metrics/coverage_metric.py +48 -0
- rubin_sim/maf/metrics/crowding_metric.py +255 -0
- rubin_sim/maf/metrics/cumulative_metric.py +46 -0
- rubin_sim/maf/metrics/dcr_metric.py +93 -0
- rubin_sim/maf/metrics/exgal_m5.py +57 -0
- rubin_sim/maf/metrics/fft_metric.py +27 -0
- rubin_sim/maf/metrics/galactic_plane_metrics.py +375 -0
- rubin_sim/maf/metrics/galplane_time_sampling_metrics.py +236 -0
- rubin_sim/maf/metrics/hourglass_metric.py +130 -0
- rubin_sim/maf/metrics/incremental_template_metric.py +255 -0
- rubin_sim/maf/metrics/kuiper_metrics.py +26 -0
- rubin_sim/maf/metrics/mo_metrics.py +1496 -0
- rubin_sim/maf/metrics/mo_summary_metrics.py +464 -0
- rubin_sim/maf/metrics/night_pointing_metric.py +70 -0
- rubin_sim/maf/metrics/optimal_m5_metric.py +94 -0
- rubin_sim/maf/metrics/pair_metric.py +69 -0
- rubin_sim/maf/metrics/periodic_detect_metric.py +133 -0
- rubin_sim/maf/metrics/phase_gap_metric.py +172 -0
- rubin_sim/maf/metrics/qso_number_counts_metric.py +138 -0
- rubin_sim/maf/metrics/scaling_metrics.py +148 -0
- rubin_sim/maf/metrics/schedview_metrics.py +39 -0
- rubin_sim/maf/metrics/season_metrics.py +344 -0
- rubin_sim/maf/metrics/simple_metrics.py +546 -0
- rubin_sim/maf/metrics/sky_sat_metric.py +18 -0
- rubin_sim/maf/metrics/sn_cadence_metric.py +104 -0
- rubin_sim/maf/metrics/sn_n_sn_metric.py +1364 -0
- rubin_sim/maf/metrics/sn_sl_metric.py +216 -0
- rubin_sim/maf/metrics/sn_snr_metric.py +715 -0
- rubin_sim/maf/metrics/snr_weight.py +24 -0
- rubin_sim/maf/metrics/star_density.py +77 -0
- rubin_sim/maf/metrics/string_count_metric.py +95 -0
- rubin_sim/maf/metrics/summary_metrics.py +201 -0
- rubin_sim/maf/metrics/surfb_metric.py +175 -0
- rubin_sim/maf/metrics/technical_metrics.py +271 -0
- rubin_sim/maf/metrics/tgaps.py +412 -0
- rubin_sim/maf/metrics/tomography_models.py +2034 -0
- rubin_sim/maf/metrics/transient_metrics.py +268 -0
- rubin_sim/maf/metrics/uniformity_metrics.py +418 -0
- rubin_sim/maf/metrics/use_metrics.py +55 -0
- rubin_sim/maf/metrics/vector_metrics.py +190 -0
- rubin_sim/maf/metrics/visit_groups_metric.py +341 -0
- rubin_sim/maf/metrics/weak_lensing_systematics_metric.py +210 -0
- rubin_sim/maf/plots/__init__.py +14 -0
- rubin_sim/maf/plots/hg_plotters.py +1117 -0
- rubin_sim/maf/plots/hourglass_plotters.py +120 -0
- rubin_sim/maf/plots/mo_plotters.py +358 -0
- rubin_sim/maf/plots/nd_plotters.py +220 -0
- rubin_sim/maf/plots/neo_distance_plotter.py +140 -0
- rubin_sim/maf/plots/night_pointing_plotter.py +96 -0
- rubin_sim/maf/plots/oned_plotters.py +114 -0
- rubin_sim/maf/plots/perceptual_rainbow.py +30 -0
- rubin_sim/maf/plots/plot_handler.py +766 -0
- rubin_sim/maf/plots/skyproj_plotters.py +540 -0
- rubin_sim/maf/plots/spatial_plotters.py +1029 -0
- rubin_sim/maf/plots/special_plotters.py +256 -0
- rubin_sim/maf/plots/two_d_plotters.py +177 -0
- rubin_sim/maf/plots/xyplotter.py +37 -0
- rubin_sim/maf/run_comparison/__init__.py +5 -0
- rubin_sim/maf/run_comparison/archive.py +584 -0
- rubin_sim/maf/run_comparison/gather_summaries.py +125 -0
- rubin_sim/maf/run_comparison/microlensing_compare.py +514 -0
- rubin_sim/maf/run_comparison/radar_plot.py +202 -0
- rubin_sim/maf/run_comparison/summary_plots.py +710 -0
- rubin_sim/maf/run_moving_calc.py +239 -0
- rubin_sim/maf/run_moving_fractions.py +128 -0
- rubin_sim/maf/run_moving_join.py +103 -0
- rubin_sim/maf/run_selfcal_metric.py +92 -0
- rubin_sim/maf/scimaf_dir.py +87 -0
- rubin_sim/maf/show_maf.py +227 -0
- rubin_sim/maf/slicers/__init__.py +13 -0
- rubin_sim/maf/slicers/base_slicer.py +513 -0
- rubin_sim/maf/slicers/base_spatial_slicer.py +202 -0
- rubin_sim/maf/slicers/healpix_sdss_slicer.py +118 -0
- rubin_sim/maf/slicers/healpix_slicer.py +189 -0
- rubin_sim/maf/slicers/healpix_subset_slicer.py +293 -0
- rubin_sim/maf/slicers/hourglass_slicer.py +37 -0
- rubin_sim/maf/slicers/mo_slicer.py +171 -0
- rubin_sim/maf/slicers/movie_slicer.py +288 -0
- rubin_sim/maf/slicers/nd_slicer.py +147 -0
- rubin_sim/maf/slicers/one_d_slicer.py +210 -0
- rubin_sim/maf/slicers/time_interval_slicers.py +283 -0
- rubin_sim/maf/slicers/uni_slicer.py +57 -0
- rubin_sim/maf/slicers/user_points_slicer.py +141 -0
- rubin_sim/maf/stackers/__init__.py +13 -0
- rubin_sim/maf/stackers/base_stacker.py +221 -0
- rubin_sim/maf/stackers/coord_stackers.py +224 -0
- rubin_sim/maf/stackers/date_stackers.py +192 -0
- rubin_sim/maf/stackers/general_stackers.py +683 -0
- rubin_sim/maf/stackers/get_col_info.py +104 -0
- rubin_sim/maf/stackers/label_stackers.py +114 -0
- rubin_sim/maf/stackers/m5_optimal_stacker.py +126 -0
- rubin_sim/maf/stackers/mo_phase.py +265 -0
- rubin_sim/maf/stackers/mo_stackers.py +486 -0
- rubin_sim/maf/stackers/n_follow_stacker.py +187 -0
- rubin_sim/maf/stackers/neo_dist_stacker.py +126 -0
- rubin_sim/maf/stackers/sdss_stackers.py +30 -0
- rubin_sim/maf/stackers/sn_stacker.py +152 -0
- rubin_sim/maf/stackers/teff_stacker.py +154 -0
- rubin_sim/maf/utils/__init__.py +6 -0
- rubin_sim/maf/utils/astrometry_utils.py +93 -0
- rubin_sim/maf/utils/generate_fov_map.py +58 -0
- rubin_sim/maf/utils/get_date_version.py +28 -0
- rubin_sim/maf/utils/maf_utils.py +212 -0
- rubin_sim/maf/utils/opsim_utils.py +259 -0
- rubin_sim/maf/utils/output_utils.py +34 -0
- rubin_sim/maf/utils/sn_n_sn_utils.py +894 -0
- rubin_sim/maf/utils/sn_utils.py +369 -0
- rubin_sim/maf/utils/stellar_mags.py +197 -0
- rubin_sim/maf/web/__init__.py +2 -0
- rubin_sim/maf/web/favicon.ico +0 -0
- rubin_sim/maf/web/maf_run_results.py +645 -0
- rubin_sim/maf/web/maf_tracking.py +139 -0
- rubin_sim/maf/web/sorttable.js +496 -0
- rubin_sim/maf/web/templates/allmetricresults.html +72 -0
- rubin_sim/maf/web/templates/configs.html +28 -0
- rubin_sim/maf/web/templates/macros.html +243 -0
- rubin_sim/maf/web/templates/master.html +294 -0
- rubin_sim/maf/web/templates/metricselect.html +91 -0
- rubin_sim/maf/web/templates/multicolor.html +147 -0
- rubin_sim/maf/web/templates/results.html +82 -0
- rubin_sim/maf/web/templates/runselect.html +58 -0
- rubin_sim/maf/web/templates/stats.html +50 -0
- rubin_sim/moving_objects/__init__.py +8 -0
- rubin_sim/moving_objects/base_obs.py +468 -0
- rubin_sim/moving_objects/cheby_fits.py +689 -0
- rubin_sim/moving_objects/cheby_values.py +231 -0
- rubin_sim/moving_objects/chebyshev_utils.py +365 -0
- rubin_sim/moving_objects/direct_obs.py +376 -0
- rubin_sim/moving_objects/make_lsst_obs.py +282 -0
- rubin_sim/moving_objects/ooephemerides.py +643 -0
- rubin_sim/moving_objects/orbits.py +507 -0
- rubin_sim/moving_objects/pre_generate.py +37 -0
- rubin_sim/moving_objects/utils.py +61 -0
- rubin_sim/phot_utils/__init__.py +7 -0
- rubin_sim/phot_utils/bandpass.py +425 -0
- rubin_sim/phot_utils/photometric_parameters.py +449 -0
- rubin_sim/phot_utils/physical_parameters.py +50 -0
- rubin_sim/phot_utils/predicted_zeropoints.py +245 -0
- rubin_sim/phot_utils/sed.py +1773 -0
- rubin_sim/phot_utils/sed_utils.py +52 -0
- rubin_sim/phot_utils/signaltonoise.py +695 -0
- rubin_sim/phot_utils/spectral_resampling.py +161 -0
- rubin_sim/satellite_constellations/__init__.py +3 -0
- rubin_sim/satellite_constellations/basis_function.py +40 -0
- rubin_sim/satellite_constellations/model_observatory.py +157 -0
- rubin_sim/satellite_constellations/sat_utils.py +488 -0
- rubin_sim/selfcal/__init__.py +4 -0
- rubin_sim/selfcal/generate_catalog.py +188 -0
- rubin_sim/selfcal/offsets.py +119 -0
- rubin_sim/selfcal/solver.py +143 -0
- rubin_sim/selfcal/star_tools.py +42 -0
- rubin_sim/sim_archive/__init__.py +14 -0
- rubin_sim/sim_archive/conda_packages.py +65 -0
- rubin_sim/sim_archive/future_vsarch.py +480 -0
- rubin_sim/sim_archive/make_snapshot.py +255 -0
- rubin_sim/sim_archive/prenight.py +216 -0
- rubin_sim/sim_archive/prenightindex.py +229 -0
- rubin_sim/sim_archive/prototype.py +1029 -0
- rubin_sim/sim_archive/sim_archive.py +680 -0
- rubin_sim/sim_archive/tempdb.py +56 -0
- rubin_sim/sim_archive/util.py +146 -0
- rubin_sim/sim_archive/vseqarchive.py +965 -0
- rubin_sim/sim_archive/vseqmetadata.py +1721 -0
- rubin_sim/skybrightness/__init__.py +5 -0
- rubin_sim/skybrightness/allsky_db.py +93 -0
- rubin_sim/skybrightness/data/ESO_Spectra/eso_tools.py +505 -0
- rubin_sim/skybrightness/data/solarSpec/package.py +22 -0
- rubin_sim/skybrightness/generate_hdf5.py +243 -0
- rubin_sim/skybrightness/interp_components.py +798 -0
- rubin_sim/skybrightness/sky_model.py +771 -0
- rubin_sim/skybrightness/twilight_func.py +83 -0
- rubin_sim/skybrightness/utils.py +91 -0
- rubin_sim-2.6.1.dev2.dist-info/METADATA +95 -0
- rubin_sim-2.6.1.dev2.dist-info/RECORD +387 -0
- rubin_sim-2.6.1.dev2.dist-info/WHEEL +5 -0
- rubin_sim-2.6.1.dev2.dist-info/entry_points.txt +24 -0
- rubin_sim-2.6.1.dev2.dist-info/licenses/LICENSE +674 -0
- rubin_sim-2.6.1.dev2.dist-info/top_level.txt +5 -0
- sql/make_vseqmeta.sql +251 -0
- tests/data/test_data.py +26 -0
- tests/data/test_ddf_grid.py +17 -0
- tests/maf/test_3x2fom.py +68 -0
- tests/maf/test_archive.py +162 -0
- tests/maf/test_basemetrics.py +99 -0
- tests/maf/test_batchcommon.py +36 -0
- tests/maf/test_batches.py +159 -0
- tests/maf/test_cadencemetrics.py +388 -0
- tests/maf/test_calibrationmetrics.py +242 -0
- tests/maf/test_color_slopes.py +71 -0
- tests/maf/test_cosmology_summaries.py +20 -0
- tests/maf/test_gathersummaries.py +48 -0
- tests/maf/test_healpixslicer.py +439 -0
- tests/maf/test_healpixsubsetslicer.py +273 -0
- tests/maf/test_hgplotters.py +145 -0
- tests/maf/test_hourglassmetric.py +33 -0
- tests/maf/test_io.py +187 -0
- tests/maf/test_json.py +169 -0
- tests/maf/test_maps.py +199 -0
- tests/maf/test_metricbundle.py +69 -0
- tests/maf/test_mometrics.py +422 -0
- tests/maf/test_movieslicer.py +216 -0
- tests/maf/test_ndslicer.py +240 -0
- tests/maf/test_neodistanceplotter.py +41 -0
- tests/maf/test_onedslicer.py +245 -0
- tests/maf/test_opsimutils.py +80 -0
- tests/maf/test_plotters.py +134 -0
- tests/maf/test_resultsdb.py +145 -0
- tests/maf/test_schedviewmetrics.py +14 -0
- tests/maf/test_simplemetrics.py +200 -0
- tests/maf/test_snmetrics.py +335 -0
- tests/maf/test_snmetrics_nsn.py +123 -0
- tests/maf/test_stackers.py +423 -0
- tests/maf/test_stellarmags.py +50 -0
- tests/maf/test_stringcount.py +26 -0
- tests/maf/test_summary_plots.py +197 -0
- tests/maf/test_summarymetrics.py +82 -0
- tests/maf/test_technicalmetrics.py +267 -0
- tests/maf/test_templatemetrics.py +86 -0
- tests/maf/test_timeintervalslicers.py +97 -0
- tests/maf/test_trackingdb.py +88 -0
- tests/maf/test_unislicer.py +116 -0
- tests/maf/test_vectormetrics.py +225 -0
- tests/maf/test_visitgroupsmetric.py +181 -0
- tests/moving_objects/test_camera.py +39 -0
- tests/moving_objects/test_chebyfits.py +188 -0
- tests/moving_objects/test_chebyshevutils.py +76 -0
- tests/moving_objects/test_chebyvalues.py +245 -0
- tests/moving_objects/test_ephemerides.py +219 -0
- tests/moving_objects/test_orbits.py +170 -0
- tests/moving_objects/test_sed_data.py +61 -0
- tests/phot_utils/test_approximatebandpasses.py +91 -0
- tests/phot_utils/test_photometricparameters.py +268 -0
- tests/phot_utils/test_photometry.py +61 -0
- tests/phot_utils/test_predicted_zeropoints.py +53 -0
- tests/phot_utils/test_read_bandpasses.py +29 -0
- tests/phot_utils/test_sed.py +368 -0
- tests/phot_utils/test_snr.py +370 -0
- tests/satellite_constellations/test_satellites.py +36 -0
- tests/sim_archive/test_make_snapshot.py +24 -0
- tests/sim_archive/test_prototype_sim_archive.py +204 -0
- tests/sim_archive/test_vseqarchive.py +947 -0
- 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
|