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,507 @@
|
|
|
1
|
+
__all__ = ("Orbits",)
|
|
2
|
+
|
|
3
|
+
import warnings
|
|
4
|
+
|
|
5
|
+
import numpy as np
|
|
6
|
+
import pandas as pd
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class Orbits:
|
|
10
|
+
"""Orbits reads, checks for required values, and stores orbit
|
|
11
|
+
parameters for moving objects.
|
|
12
|
+
|
|
13
|
+
self.orbits stores the orbital parameters, as a pandas dataframe.
|
|
14
|
+
self.dataCols defines the columns required,
|
|
15
|
+
although obj_id, H, g, and sed_filename are optional.
|
|
16
|
+
"""
|
|
17
|
+
|
|
18
|
+
def __init__(self):
|
|
19
|
+
self.orbits = None
|
|
20
|
+
self.orb_format = None
|
|
21
|
+
|
|
22
|
+
# Specify the required columns/values in the self.orbits dataframe.
|
|
23
|
+
# Which columns are required depends on self.orb_format.
|
|
24
|
+
self.data_cols = {}
|
|
25
|
+
self.data_cols["COM"] = [
|
|
26
|
+
"obj_id",
|
|
27
|
+
"q",
|
|
28
|
+
"e",
|
|
29
|
+
"inc",
|
|
30
|
+
"Omega",
|
|
31
|
+
"argPeri",
|
|
32
|
+
"tPeri",
|
|
33
|
+
"epoch",
|
|
34
|
+
"H",
|
|
35
|
+
"g",
|
|
36
|
+
"sed_filename",
|
|
37
|
+
]
|
|
38
|
+
self.data_cols["KEP"] = [
|
|
39
|
+
"obj_id",
|
|
40
|
+
"a",
|
|
41
|
+
"e",
|
|
42
|
+
"inc",
|
|
43
|
+
"Omega",
|
|
44
|
+
"argPeri",
|
|
45
|
+
"meanAnomaly",
|
|
46
|
+
"epoch",
|
|
47
|
+
"H",
|
|
48
|
+
"g",
|
|
49
|
+
"sed_filename",
|
|
50
|
+
]
|
|
51
|
+
self.data_cols["CAR"] = [
|
|
52
|
+
"obj_id",
|
|
53
|
+
"x",
|
|
54
|
+
"y",
|
|
55
|
+
"z",
|
|
56
|
+
"xdot",
|
|
57
|
+
"ydot",
|
|
58
|
+
"zdot",
|
|
59
|
+
"epoch",
|
|
60
|
+
"H",
|
|
61
|
+
"g",
|
|
62
|
+
"sed_filename",
|
|
63
|
+
]
|
|
64
|
+
|
|
65
|
+
def __len__(self):
|
|
66
|
+
return len(self.orbits)
|
|
67
|
+
|
|
68
|
+
def __getitem__(self, i):
|
|
69
|
+
orb = Orbits()
|
|
70
|
+
orb.set_orbits(self.orbits.iloc[i])
|
|
71
|
+
return orb
|
|
72
|
+
|
|
73
|
+
def __iter__(self):
|
|
74
|
+
for i, orbit in self.orbits.iterrows():
|
|
75
|
+
orb = Orbits()
|
|
76
|
+
orb.set_orbits(orbit)
|
|
77
|
+
yield orb
|
|
78
|
+
|
|
79
|
+
def __eq__(self, other_orbits):
|
|
80
|
+
if isinstance(other_orbits, Orbits):
|
|
81
|
+
if self.orb_format != other_orbits.orb_format:
|
|
82
|
+
return False
|
|
83
|
+
for col in self.data_cols[self.orb_format]:
|
|
84
|
+
if not np.all(self.orbits[col].values == other_orbits.orbits[col].values):
|
|
85
|
+
return False
|
|
86
|
+
else:
|
|
87
|
+
return True
|
|
88
|
+
else:
|
|
89
|
+
return False
|
|
90
|
+
|
|
91
|
+
def __neq__(self, other_orbits):
|
|
92
|
+
if self == other_orbits:
|
|
93
|
+
return False
|
|
94
|
+
else:
|
|
95
|
+
return True
|
|
96
|
+
|
|
97
|
+
def set_orbits(self, orbits):
|
|
98
|
+
"""Set and validate orbital parameters contain all required values.
|
|
99
|
+
|
|
100
|
+
Sets self.orbits and self.orb_format.
|
|
101
|
+
If objid is not present in orbits,
|
|
102
|
+
a sequential series of integers will be used.
|
|
103
|
+
If H is not present in orbits,
|
|
104
|
+
a default value of 20 will be used.
|
|
105
|
+
If g is not present in orbits,
|
|
106
|
+
a default value of 0.15 will be used.
|
|
107
|
+
If sed_filename is not present in orbits,
|
|
108
|
+
either C or S type will be assigned according to the
|
|
109
|
+
semi-major axis value.
|
|
110
|
+
|
|
111
|
+
Parameters
|
|
112
|
+
----------
|
|
113
|
+
orbits : `pd.DataFrame`, `pd.Series` or `np.ndarray`
|
|
114
|
+
Array-like object containing orbital parameter information.
|
|
115
|
+
"""
|
|
116
|
+
# Do we have a single item or multiples?
|
|
117
|
+
if isinstance(orbits, pd.Series):
|
|
118
|
+
# Passed a single SSO in Series, convert to a DataFrame.
|
|
119
|
+
orbits = pd.DataFrame([orbits])
|
|
120
|
+
elif isinstance(orbits, np.ndarray):
|
|
121
|
+
# Passed a numpy array, convert to DataFrame.
|
|
122
|
+
orbits = pd.DataFrame.from_records(orbits)
|
|
123
|
+
elif isinstance(orbits, np.record):
|
|
124
|
+
# This was a single object in a numpy array
|
|
125
|
+
orbits = pd.DataFrame.from_records([orbits], columns=orbits.dtype.names)
|
|
126
|
+
elif isinstance(orbits, pd.DataFrame):
|
|
127
|
+
# This was a pandas dataframe ..
|
|
128
|
+
# but we probably want to drop the index and recount.
|
|
129
|
+
orbits.reset_index(drop=True, inplace=True)
|
|
130
|
+
|
|
131
|
+
if "index" in orbits:
|
|
132
|
+
del orbits["index"]
|
|
133
|
+
|
|
134
|
+
n_sso = len(orbits)
|
|
135
|
+
|
|
136
|
+
# Error if orbits is empty
|
|
137
|
+
# (this avoids hard-to-interpret error messages from pyoorb).
|
|
138
|
+
if n_sso == 0:
|
|
139
|
+
raise ValueError("Length of the orbits dataframe was 0.")
|
|
140
|
+
|
|
141
|
+
# Discover which type of orbital parameters we have on disk.
|
|
142
|
+
self.orb_format = None
|
|
143
|
+
if "FORMAT" in orbits:
|
|
144
|
+
if ~(orbits["FORMAT"] == orbits["FORMAT"].iloc[0]).all():
|
|
145
|
+
raise ValueError("All orbital elements in the set should have the same FORMAT.")
|
|
146
|
+
self.orb_format = orbits["FORMAT"].iloc[0]
|
|
147
|
+
# Backwards compatibility .. a bit.
|
|
148
|
+
# CART is deprecated, so swap it to CAR.
|
|
149
|
+
if self.orb_format == "CART":
|
|
150
|
+
self.orb_format = "CAR"
|
|
151
|
+
del orbits["FORMAT"]
|
|
152
|
+
# Check that the orbit format is approximately right.
|
|
153
|
+
if self.orb_format == "COM":
|
|
154
|
+
if "q" not in orbits:
|
|
155
|
+
raise ValueError('The stated format was COM, but "q" not present in orbital elements?')
|
|
156
|
+
if self.orb_format == "KEP":
|
|
157
|
+
if "a" not in orbits:
|
|
158
|
+
raise ValueError('The stated format was KEP, but "a" not present in orbital elements?')
|
|
159
|
+
if self.orb_format == "CAR":
|
|
160
|
+
if "x" not in orbits:
|
|
161
|
+
raise ValueError('The stated format was CAR but "x" not present in orbital elements?')
|
|
162
|
+
if self.orb_format is None:
|
|
163
|
+
# Try to figure out the format, if it wasn't provided.
|
|
164
|
+
if "q" in orbits:
|
|
165
|
+
self.orb_format = "COM"
|
|
166
|
+
elif "a" in orbits:
|
|
167
|
+
self.orb_format = "KEP"
|
|
168
|
+
elif "x" in orbits:
|
|
169
|
+
self.orb_format = "CAR"
|
|
170
|
+
else:
|
|
171
|
+
raise ValueError(
|
|
172
|
+
"Can't determine orbital type, as neither q, a or x in input orbital elements.\n"
|
|
173
|
+
"Was attempting to base orbital element quantities on header row, "
|
|
174
|
+
"with columns: \n%s" % orbits.columns
|
|
175
|
+
)
|
|
176
|
+
|
|
177
|
+
# Check that the orbit epoch is within a 'reasonable' range,
|
|
178
|
+
# to detect possible column mismatches.
|
|
179
|
+
general_epoch = orbits["epoch"].head(1).values[0]
|
|
180
|
+
# Look for epochs between 1800 and 2200 -
|
|
181
|
+
# this is primarily to check if people used MJD (and not JD).
|
|
182
|
+
expect_min_epoch = -21503.0
|
|
183
|
+
expect_max_epoch = 124594.0
|
|
184
|
+
if general_epoch < expect_min_epoch or general_epoch > expect_max_epoch:
|
|
185
|
+
raise ValueError(
|
|
186
|
+
"The epoch detected for this orbit is odd - %f. "
|
|
187
|
+
"Expecting a value between %.1f and %.1f (MJD!)"
|
|
188
|
+
% (general_epoch, expect_min_epoch, expect_max_epoch)
|
|
189
|
+
)
|
|
190
|
+
|
|
191
|
+
# If these columns are not available in the input data,
|
|
192
|
+
# auto-generate them.
|
|
193
|
+
if "obj_id" not in orbits:
|
|
194
|
+
obj_id = np.arange(0, n_sso, 1)
|
|
195
|
+
orbits = orbits.assign(obj_id=obj_id)
|
|
196
|
+
if "H" not in orbits:
|
|
197
|
+
orbits = orbits.assign(H=20.0)
|
|
198
|
+
if "g" not in orbits:
|
|
199
|
+
orbits = orbits.assign(g=0.15)
|
|
200
|
+
if "sed_filename" not in orbits:
|
|
201
|
+
orbits = orbits.assign(sed_filename=self.assign_sed(orbits))
|
|
202
|
+
|
|
203
|
+
# Make sure we gave all the columns we need.
|
|
204
|
+
for col in self.data_cols[self.orb_format]:
|
|
205
|
+
if col not in orbits:
|
|
206
|
+
raise ValueError(
|
|
207
|
+
"Missing required orbital element %s for orbital format type %s" % (col, self.orb_format)
|
|
208
|
+
)
|
|
209
|
+
|
|
210
|
+
# Check to see if we have duplicates.
|
|
211
|
+
if len(orbits["obj_id"].unique()) != n_sso:
|
|
212
|
+
warnings.warn(
|
|
213
|
+
"There are duplicates in the orbit obj_id values" + " - was this intended? (continuing)."
|
|
214
|
+
)
|
|
215
|
+
# All is good.
|
|
216
|
+
self.orbits = orbits
|
|
217
|
+
|
|
218
|
+
def assign_sed(self, orbits, random_seed=None):
|
|
219
|
+
"""Assign either a C or S type SED,
|
|
220
|
+
depending on the semi-major axis of the object.
|
|
221
|
+
P(C type) = 0 (a<2); 0.5*a - 1 (2<a<4); 1 (a > 4),
|
|
222
|
+
based on figure 23 from Ivezic et al 2001 (AJ, 122, 2749).
|
|
223
|
+
|
|
224
|
+
Parameters
|
|
225
|
+
----------
|
|
226
|
+
orbits : `pd.DataFrame`, `pd.Series` or `np.ndarray`
|
|
227
|
+
Array-like object containing orbital parameter information.
|
|
228
|
+
|
|
229
|
+
Returns
|
|
230
|
+
-------
|
|
231
|
+
sedvals : `np.ndarray`
|
|
232
|
+
Array containing the SED type for each object in 'orbits'.
|
|
233
|
+
"""
|
|
234
|
+
# using fig. 23 from Ivezic et al. 2001 (AJ, 122, 2749),
|
|
235
|
+
# we can approximate the sed types with a simple linear form:
|
|
236
|
+
# p(C) = 0 for a<2
|
|
237
|
+
# p(C) = 0.5*a-1 for 2<a<4
|
|
238
|
+
# p(C) = 1 for a>4
|
|
239
|
+
# where a is semi-major axis, and p(C) is the probability that
|
|
240
|
+
# an asteroid is C type, with p(S)=1-p(C) for S types.
|
|
241
|
+
if "a" in orbits:
|
|
242
|
+
a = orbits["a"]
|
|
243
|
+
elif "q" in orbits:
|
|
244
|
+
a = orbits["q"] / (1 - orbits["e"])
|
|
245
|
+
elif "x" in orbits:
|
|
246
|
+
# This isn't right, but it's a placeholder to make it work for now.
|
|
247
|
+
a = np.sqrt(orbits["x"] ** 2 + orbits["y"] ** 2 + orbits["z"] ** 2)
|
|
248
|
+
else:
|
|
249
|
+
raise ValueError("Need either a or q (plus e) in orbit data frame.")
|
|
250
|
+
|
|
251
|
+
if not hasattr(self, "_rng"):
|
|
252
|
+
if random_seed is not None:
|
|
253
|
+
self._rng = np.random.RandomState(random_seed)
|
|
254
|
+
else:
|
|
255
|
+
self._rng = np.random.RandomState(42)
|
|
256
|
+
|
|
257
|
+
chance = self._rng.random_sample(len(orbits))
|
|
258
|
+
prob_c = 0.5 * a - 1.0
|
|
259
|
+
# if chance <= prob_c:
|
|
260
|
+
sedvals = np.where(chance <= prob_c, "C.dat", "S.dat")
|
|
261
|
+
return sedvals
|
|
262
|
+
|
|
263
|
+
def read_orbits(self, orbit_file, delim=None, skiprows=None):
|
|
264
|
+
"""Read orbits from a file.
|
|
265
|
+
|
|
266
|
+
This generates a pandas dataframe containing columns matching dataCols,
|
|
267
|
+
for the appropriate orbital parameter format.
|
|
268
|
+
(currently accepts COM, KEP or CAR formats).
|
|
269
|
+
|
|
270
|
+
After reading and standardizing the column names,
|
|
271
|
+
calls self.set_orbits to validate the
|
|
272
|
+
orbital parameters.
|
|
273
|
+
Expects angles in orbital element formats to be in degrees.
|
|
274
|
+
|
|
275
|
+
Note that readOrbits uses pandas.read_csv to read the data file
|
|
276
|
+
with the orbital parameters.
|
|
277
|
+
Thus, it should have column headers specifying the column names ..
|
|
278
|
+
unless skiprows = -1 or there is just no header line at all.
|
|
279
|
+
in which case it is assumed to be a standard DES format file,
|
|
280
|
+
with no header line.
|
|
281
|
+
|
|
282
|
+
Parameters
|
|
283
|
+
----------
|
|
284
|
+
orbit_file : `str`
|
|
285
|
+
The name of the input file with orbital parameter information.
|
|
286
|
+
delim : `str`, optional
|
|
287
|
+
The delimiter for the input orbit file.
|
|
288
|
+
Default is None, will use delim_whitespace=True.
|
|
289
|
+
skiprows : `int`, optional
|
|
290
|
+
The number of rows to skip before reading the header information.
|
|
291
|
+
Default is None, which will trigger a search of the file for
|
|
292
|
+
the header columns.
|
|
293
|
+
"""
|
|
294
|
+
names = None
|
|
295
|
+
|
|
296
|
+
# If skiprows is set, then we will assume the user has
|
|
297
|
+
# handled this so that the first line read has the header information.
|
|
298
|
+
# But, if skiprows is not set, then we have to do some checking to
|
|
299
|
+
# see if there is header information and which row it might start in.
|
|
300
|
+
if skiprows is None:
|
|
301
|
+
skiprows = -1
|
|
302
|
+
# Figure out whether the header is in the first line,
|
|
303
|
+
# or if there are rows to skip.
|
|
304
|
+
# We need to do a bit of juggling to do this before pandas
|
|
305
|
+
# reads the whole orbit file.
|
|
306
|
+
with open(orbit_file, "r") as fp:
|
|
307
|
+
headervalues = None
|
|
308
|
+
for line in fp:
|
|
309
|
+
values = line.split()
|
|
310
|
+
try:
|
|
311
|
+
# If it is a valid orbit line,
|
|
312
|
+
# we expect column 3 to be a number.
|
|
313
|
+
float(values[3])
|
|
314
|
+
# And if it worked, we're done here (it's an orbit) -
|
|
315
|
+
# go on to parsing header values.
|
|
316
|
+
break
|
|
317
|
+
except (ValueError, IndexError):
|
|
318
|
+
# This wasn't a valid number or there wasn't
|
|
319
|
+
# anything in the third value.
|
|
320
|
+
# So this is either the header line or it's a
|
|
321
|
+
# comment line before the header columns.
|
|
322
|
+
skiprows += 1
|
|
323
|
+
headervalues = values
|
|
324
|
+
|
|
325
|
+
if headervalues is not None: # (and skiprows > -1)
|
|
326
|
+
# There is a header, but we also need to check if there
|
|
327
|
+
# is a comment key at the start of the proper header line.
|
|
328
|
+
# (Because this varies as well).
|
|
329
|
+
linestart = headervalues[0]
|
|
330
|
+
if linestart == "#" or linestart == "!!" or linestart == "##":
|
|
331
|
+
names = headervalues[1:]
|
|
332
|
+
else:
|
|
333
|
+
names = headervalues
|
|
334
|
+
# Add 1 to skiprows, so that we skip the header column line.
|
|
335
|
+
skiprows += 1
|
|
336
|
+
|
|
337
|
+
# So now skiprows is a value.
|
|
338
|
+
# If it is -1, then there is no header information.
|
|
339
|
+
if skiprows == -1:
|
|
340
|
+
# No header; assume it's a typical DES file -
|
|
341
|
+
# we'll assign the column names based on the FORMAT.
|
|
342
|
+
names_com = (
|
|
343
|
+
"obj_id",
|
|
344
|
+
"FORMAT",
|
|
345
|
+
"q",
|
|
346
|
+
"e",
|
|
347
|
+
"i",
|
|
348
|
+
"node",
|
|
349
|
+
"argperi",
|
|
350
|
+
"t_p",
|
|
351
|
+
"H",
|
|
352
|
+
"epoch",
|
|
353
|
+
"INDEX",
|
|
354
|
+
"N_PAR",
|
|
355
|
+
"MOID",
|
|
356
|
+
"COMPCODE",
|
|
357
|
+
)
|
|
358
|
+
names_kep = (
|
|
359
|
+
"obj_id",
|
|
360
|
+
"FORMAT",
|
|
361
|
+
"a",
|
|
362
|
+
"e",
|
|
363
|
+
"i",
|
|
364
|
+
"node",
|
|
365
|
+
"argperi",
|
|
366
|
+
"meanAnomaly",
|
|
367
|
+
"H",
|
|
368
|
+
"epoch",
|
|
369
|
+
"INDEX",
|
|
370
|
+
"N_PAR",
|
|
371
|
+
"MOID",
|
|
372
|
+
"COMPCODE",
|
|
373
|
+
)
|
|
374
|
+
names_car = (
|
|
375
|
+
"obj_id",
|
|
376
|
+
"FORMAT",
|
|
377
|
+
"x",
|
|
378
|
+
"y",
|
|
379
|
+
"z",
|
|
380
|
+
"xdot",
|
|
381
|
+
"ydot",
|
|
382
|
+
"zdot",
|
|
383
|
+
"H",
|
|
384
|
+
"epoch",
|
|
385
|
+
"INDEX",
|
|
386
|
+
"N_PAR",
|
|
387
|
+
"MOID",
|
|
388
|
+
"COMPCODE",
|
|
389
|
+
)
|
|
390
|
+
# First use names_com, and then change if required.
|
|
391
|
+
orbits = pd.read_csv(orbit_file, sep=r"\s+", header=None, names=names_com)
|
|
392
|
+
|
|
393
|
+
if orbits["FORMAT"][0] == "KEP":
|
|
394
|
+
orbits.columns = names_kep
|
|
395
|
+
elif orbits["FORMAT"][0] == "CAR":
|
|
396
|
+
orbits.columns = names_car
|
|
397
|
+
|
|
398
|
+
else:
|
|
399
|
+
if delim is None:
|
|
400
|
+
orbits = pd.read_csv(orbit_file, sep=r"\s+", skiprows=skiprows, names=names)
|
|
401
|
+
else:
|
|
402
|
+
orbits = pd.read_csv(orbit_file, sep=delim, skiprows=skiprows, names=names)
|
|
403
|
+
|
|
404
|
+
# Drop some columns that are typically present in DES files
|
|
405
|
+
# but that we don't need.
|
|
406
|
+
if "INDEX" in orbits:
|
|
407
|
+
del orbits["INDEX"]
|
|
408
|
+
if "N_PAR" in orbits:
|
|
409
|
+
del orbits["N_PAR"]
|
|
410
|
+
if "MOID" in orbits:
|
|
411
|
+
del orbits["MOID"]
|
|
412
|
+
if "COMPCODE" in orbits:
|
|
413
|
+
del orbits["COMPCODE"]
|
|
414
|
+
if "tmp" in orbits:
|
|
415
|
+
del orbits["tmp"]
|
|
416
|
+
|
|
417
|
+
# Normalize the column names to standard values and
|
|
418
|
+
# identify the orbital element types.
|
|
419
|
+
sso_cols = orbits.columns.values.tolist()
|
|
420
|
+
|
|
421
|
+
# These are the alternative possibilities for various column headers
|
|
422
|
+
# (depending on file version, origin, etc.)
|
|
423
|
+
# that might need remapping to our standardized names.
|
|
424
|
+
alt_names = {}
|
|
425
|
+
alt_names["obj_id"] = [
|
|
426
|
+
"obj_id",
|
|
427
|
+
"objid",
|
|
428
|
+
"!!ObjID",
|
|
429
|
+
"!!OID",
|
|
430
|
+
"!!S3MID",
|
|
431
|
+
"OID",
|
|
432
|
+
"S3MID" "objid(int)",
|
|
433
|
+
"full_name",
|
|
434
|
+
"#name",
|
|
435
|
+
]
|
|
436
|
+
alt_names["q"] = ["q"]
|
|
437
|
+
alt_names["a"] = ["a"]
|
|
438
|
+
alt_names["e"] = ["e", "ecc"]
|
|
439
|
+
alt_names["inc"] = ["inc", "i", "i(deg)", "incl"]
|
|
440
|
+
alt_names["Omega"] = [
|
|
441
|
+
"Omega",
|
|
442
|
+
"omega",
|
|
443
|
+
"node",
|
|
444
|
+
"om",
|
|
445
|
+
"node(deg)",
|
|
446
|
+
"BigOmega",
|
|
447
|
+
"Omega/node",
|
|
448
|
+
"longNode",
|
|
449
|
+
]
|
|
450
|
+
alt_names["argPeri"] = [
|
|
451
|
+
"argPeri",
|
|
452
|
+
"argperi",
|
|
453
|
+
"omega/argperi",
|
|
454
|
+
"w",
|
|
455
|
+
"argperi(deg)",
|
|
456
|
+
"peri",
|
|
457
|
+
]
|
|
458
|
+
alt_names["tPeri"] = ["tPeri", "t_p", "timeperi", "t_peri", "T_peri"]
|
|
459
|
+
alt_names["epoch"] = ["epoch", "t_0", "Epoch", "epoch_mjd"]
|
|
460
|
+
alt_names["H"] = ["H", "magH", "magHv", "Hv", "H_v"]
|
|
461
|
+
alt_names["g"] = ["g", "phaseV", "phase", "gV", "phase_g", "G"]
|
|
462
|
+
alt_names["meanAnomaly"] = ["meanAnomaly", "meanAnom", "M", "ma"]
|
|
463
|
+
alt_names["sed_filename"] = ["sed_filename", "sed"]
|
|
464
|
+
alt_names["xdot"] = ["xdot", "xDot"]
|
|
465
|
+
alt_names["ydot"] = ["ydot", "yDot"]
|
|
466
|
+
alt_names["zdot"] = ["zdot", "zDot"]
|
|
467
|
+
|
|
468
|
+
# Update column names that match any of the alternatives above.
|
|
469
|
+
for name, alternatives in alt_names.items():
|
|
470
|
+
intersection = list(set(alternatives) & set(sso_cols))
|
|
471
|
+
if len(intersection) > 1:
|
|
472
|
+
raise ValueError(
|
|
473
|
+
"Received too many possible matches to %s in orbit file %s" % (name, orbit_file)
|
|
474
|
+
)
|
|
475
|
+
if len(intersection) == 1:
|
|
476
|
+
idx = sso_cols.index(intersection[0])
|
|
477
|
+
sso_cols[idx] = name
|
|
478
|
+
# Assign the new column names back to the orbits dataframe.
|
|
479
|
+
orbits.columns = sso_cols
|
|
480
|
+
|
|
481
|
+
# Failing on negative inclinations.
|
|
482
|
+
if "inc" in orbits.keys():
|
|
483
|
+
if np.min(orbits["inc"]) < 0:
|
|
484
|
+
negative_incs = np.where(orbits["inc"].values < 0)[0]
|
|
485
|
+
negative_ids = orbits["obj_id"].values[negative_incs]
|
|
486
|
+
ValueError("Negative orbital inclinations not supported. Problem obj_ids=%s" % negative_ids)
|
|
487
|
+
|
|
488
|
+
# Validate and assign orbits to self.
|
|
489
|
+
self.set_orbits(orbits)
|
|
490
|
+
|
|
491
|
+
def update_orbits(self, neworb):
|
|
492
|
+
"""Update existing orbits with new values,
|
|
493
|
+
leaving OrbitIds, H, g, and sed_filenames in place.
|
|
494
|
+
|
|
495
|
+
Example use: transform orbital parameters (using PyOrbEphemerides)
|
|
496
|
+
and then replace original values.
|
|
497
|
+
Example use: propagate orbital parameters (using PyOrbEphemerides)
|
|
498
|
+
and then replace original values.
|
|
499
|
+
|
|
500
|
+
Parameters
|
|
501
|
+
----------
|
|
502
|
+
neworb: `pd.DataFrame`
|
|
503
|
+
"""
|
|
504
|
+
col_orig = ["obj_id", "sed_filename"]
|
|
505
|
+
new_order = ["obj_id"] + [n for n in neworb.columns] + ["sed_filename"]
|
|
506
|
+
updated_orbits = neworb.join(self.orbits[col_orig])[new_order]
|
|
507
|
+
self.set_orbits(updated_orbits)
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import glob
|
|
2
|
+
import os
|
|
3
|
+
|
|
4
|
+
import numpy as np
|
|
5
|
+
|
|
6
|
+
from rubin_sim.data import get_data_dir
|
|
7
|
+
from rubin_sim.moving_objects import DirectObs, Orbits
|
|
8
|
+
|
|
9
|
+
if __name__ == "__main__":
|
|
10
|
+
"""Pre-generate a series of nightly ephemerides with a 1-night timestep."""
|
|
11
|
+
mjd_start = 60676.0
|
|
12
|
+
length = 365.25 * 12 # How long to pre-compute for
|
|
13
|
+
dtime = 1
|
|
14
|
+
mjds = np.arange(mjd_start, mjd_start + length, dtime)
|
|
15
|
+
|
|
16
|
+
orbit_files = glob.glob(os.path.join(get_data_dir(), "orbits/") + "*.txt")
|
|
17
|
+
output_dir = os.path.join(os.path.join(get_data_dir(), "orbits_precompute/"))
|
|
18
|
+
|
|
19
|
+
names = ["ra", "dec"]
|
|
20
|
+
types = [float] * 2
|
|
21
|
+
dt = list(zip(names, types))
|
|
22
|
+
|
|
23
|
+
for filename in orbit_files:
|
|
24
|
+
print("working on %s" % filename)
|
|
25
|
+
orbits = Orbits()
|
|
26
|
+
orbits.read_orbits(filename)
|
|
27
|
+
# Array to hold results
|
|
28
|
+
results = np.zeros((len(orbits.orbits), np.size(mjds)), dt)
|
|
29
|
+
do = DirectObs()
|
|
30
|
+
_temp_positions = do.generate_ephemerides(orbits, mjds, eph_mode="nbody", eph_type="basic")
|
|
31
|
+
results["ra"] += _temp_positions["ra"]
|
|
32
|
+
results["dec"] += _temp_positions["dec"]
|
|
33
|
+
np.savez(
|
|
34
|
+
os.path.join(output_dir, os.path.basename(filename).replace(".txt", ".npz")),
|
|
35
|
+
positions=results,
|
|
36
|
+
mjds=mjds,
|
|
37
|
+
)
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
__all__ = ("read_observations",)
|
|
2
|
+
|
|
3
|
+
import logging
|
|
4
|
+
|
|
5
|
+
from rubin_sim.maf.utils import get_sim_data
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
def read_observations(simfile, colmap, constraint=None, dbcols=None):
|
|
9
|
+
"""Read the opsim database.
|
|
10
|
+
|
|
11
|
+
Parameters
|
|
12
|
+
----------
|
|
13
|
+
simfile : `str`
|
|
14
|
+
Name (& path) of the opsim database file.
|
|
15
|
+
colmap : `dict`
|
|
16
|
+
colmap dictionary (from rubin_sim.maf.batches.ColMapDict)
|
|
17
|
+
constraint : `str`, optional
|
|
18
|
+
Optional SQL constraint (minus 'where') on the data to read from db.
|
|
19
|
+
Default is None.
|
|
20
|
+
dbcols : `list` of [`str`], optional
|
|
21
|
+
List of additional columns to query from the db and add to the
|
|
22
|
+
output observations.
|
|
23
|
+
Default None.
|
|
24
|
+
|
|
25
|
+
Returns
|
|
26
|
+
-------
|
|
27
|
+
simdata : `np.ndarray`, (N)
|
|
28
|
+
The OpSim data read from the database.
|
|
29
|
+
"""
|
|
30
|
+
if "rotSkyPos" not in colmap:
|
|
31
|
+
colmap["rotSkyPos"] = "rotSkyPos"
|
|
32
|
+
|
|
33
|
+
# Set the minimum required columns.
|
|
34
|
+
min_cols = [
|
|
35
|
+
colmap["mjd"],
|
|
36
|
+
colmap["night"],
|
|
37
|
+
colmap["ra"],
|
|
38
|
+
colmap["dec"],
|
|
39
|
+
colmap["filter"],
|
|
40
|
+
colmap["exptime"],
|
|
41
|
+
colmap["seeingGeom"],
|
|
42
|
+
colmap["fiveSigmaDepth"],
|
|
43
|
+
]
|
|
44
|
+
if dbcols is not None:
|
|
45
|
+
min_cols += dbcols
|
|
46
|
+
|
|
47
|
+
more_cols = [
|
|
48
|
+
colmap["rotSkyPos"],
|
|
49
|
+
colmap["seeingEff"],
|
|
50
|
+
"solarElong",
|
|
51
|
+
"observationId",
|
|
52
|
+
]
|
|
53
|
+
|
|
54
|
+
cols = min_cols + more_cols
|
|
55
|
+
cols = list(set(cols))
|
|
56
|
+
logging.info("Querying for columns:\n %s" % (cols))
|
|
57
|
+
|
|
58
|
+
# Go ahead and query for all of the observations.
|
|
59
|
+
simdata = get_sim_data(simfile, constraint, cols)
|
|
60
|
+
logging.info("Queried data from opsim %s, fetched %d visits." % (simfile, len(simdata)))
|
|
61
|
+
return simdata
|