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,219 @@
|
|
|
1
|
+
import os
|
|
2
|
+
import unittest
|
|
3
|
+
|
|
4
|
+
import numpy as np
|
|
5
|
+
import pandas as pd
|
|
6
|
+
from astropy.time import Time
|
|
7
|
+
from rubin_scheduler.data import get_data_dir
|
|
8
|
+
|
|
9
|
+
from rubin_sim.moving_objects import Orbits, PyOrbEphemerides
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
@unittest.skip("Temporary skip until ephemerides replaced")
|
|
13
|
+
class TestPyOrbEphemerides(unittest.TestCase):
|
|
14
|
+
def setUp(self):
|
|
15
|
+
self.testdir = os.path.join(get_data_dir(), "tests", "orbits_testdata")
|
|
16
|
+
self.orbits = Orbits()
|
|
17
|
+
self.orbits.read_orbits(os.path.join(self.testdir, "test_orbitsQ.des"))
|
|
18
|
+
self.orbits_kep = Orbits()
|
|
19
|
+
self.orbits_kep.read_orbits(os.path.join(self.testdir, "test_orbitsA.des"))
|
|
20
|
+
self.ephems = PyOrbEphemerides()
|
|
21
|
+
self.ephems.set_orbits(self.orbits)
|
|
22
|
+
self.len_ephems_basic = 11
|
|
23
|
+
self.len_ephems_full = 34
|
|
24
|
+
|
|
25
|
+
def tear_down(self):
|
|
26
|
+
del self.orbits
|
|
27
|
+
del self.orbits_kep
|
|
28
|
+
del self.ephems
|
|
29
|
+
|
|
30
|
+
def test_which_pyoorb(self):
|
|
31
|
+
import pyoorb
|
|
32
|
+
|
|
33
|
+
print(pyoorb.__file__)
|
|
34
|
+
|
|
35
|
+
def test_set_orbits(self):
|
|
36
|
+
# Test that we can set orbits.
|
|
37
|
+
self.ephems.set_orbits(self.orbits)
|
|
38
|
+
# Test that setting with an empty orbit object fails.
|
|
39
|
+
# (Avoids hard-to-interpret errors from pyoorb).
|
|
40
|
+
with self.assertRaises(ValueError):
|
|
41
|
+
empty_orb = Orbits()
|
|
42
|
+
empty = pd.DataFrame([], columns=self.orbits.data_cols["KEP"])
|
|
43
|
+
empty_orb.set_orbits(empty)
|
|
44
|
+
self.ephems.set_orbits(empty_orb)
|
|
45
|
+
|
|
46
|
+
def test_convert_to_oorb_array(self):
|
|
47
|
+
# Check that orbital elements are converted.
|
|
48
|
+
self.ephems._convert_to_oorb_elem(self.orbits.orbits, self.orbits.orb_format)
|
|
49
|
+
self.assertEqual(len(self.ephems.oorb_elem), len(self.orbits))
|
|
50
|
+
self.assertEqual(self.ephems.oorb_elem[0][7], 2)
|
|
51
|
+
self.assertEqual(self.ephems.oorb_elem[0][9], 3)
|
|
52
|
+
self.assertEqual(self.ephems.oorb_elem[0][1], self.orbits.orbits["q"][0])
|
|
53
|
+
# Test that we can convert KEP orbital elements too.
|
|
54
|
+
self.ephems._convert_to_oorb_elem(self.orbits_kep.orbits, self.orbits_kep.orb_format)
|
|
55
|
+
self.assertEqual(len(self.ephems.oorb_elem), len(self.orbits_kep))
|
|
56
|
+
self.assertEqual(self.ephems.oorb_elem[0][7], 3)
|
|
57
|
+
self.assertEqual(self.ephems.oorb_elem[0][1], self.orbits_kep.orbits["a"][0])
|
|
58
|
+
|
|
59
|
+
def test_convert_from_oorb_array(self):
|
|
60
|
+
# Check that we can convert orbital elements TO oorb format and back
|
|
61
|
+
# without losing info
|
|
62
|
+
# (except ObjId -- we will lose that unless we use updateOrbits.)
|
|
63
|
+
self.ephems._convert_to_oorb_elem(self.orbits.orbits, self.orbits.orb_format)
|
|
64
|
+
new_orbits = Orbits()
|
|
65
|
+
new_orbits.set_orbits(self.orbits.orbits)
|
|
66
|
+
new_orbits.update_orbits(self.ephems.convert_from_oorb_elem())
|
|
67
|
+
self.assertEqual(new_orbits, self.orbits)
|
|
68
|
+
|
|
69
|
+
def test_convert_times(self):
|
|
70
|
+
times = np.arange(49353, 49353 + 10, 0.5)
|
|
71
|
+
eph_times = self.ephems._convert_times(times, "UTC")
|
|
72
|
+
# Check that shape of eph_times is correct. (times x 2)
|
|
73
|
+
self.assertEqual(eph_times.shape[0], len(times))
|
|
74
|
+
self.assertEqual(eph_times.shape[1], 2)
|
|
75
|
+
# Check that 'timescale' for eph_times is correct.
|
|
76
|
+
self.assertEqual(eph_times[0][1], 1)
|
|
77
|
+
eph_times = self.ephems._convert_times(times, "TAI")
|
|
78
|
+
self.assertEqual(eph_times[0][1], 4)
|
|
79
|
+
|
|
80
|
+
def test_oorb_ephemeris(self):
|
|
81
|
+
self.ephems.set_orbits(self.orbits)
|
|
82
|
+
times = np.arange(49353, 49353 + 3, 0.25)
|
|
83
|
+
eph_times = self.ephems._convert_times(times)
|
|
84
|
+
# Basic ephemerides.
|
|
85
|
+
oorb_ephs = self.ephems._generate_oorb_ephs_basic(eph_times, obscode=807, eph_mode="N")
|
|
86
|
+
# Check that it returned the right sort of array.
|
|
87
|
+
self.assertEqual(
|
|
88
|
+
oorb_ephs.shape,
|
|
89
|
+
(len(self.ephems.oorb_elem), len(times), self.len_ephems_basic),
|
|
90
|
+
)
|
|
91
|
+
# Full ephemerides
|
|
92
|
+
oorb_ephs = self.ephems._generate_oorb_ephs_full(eph_times, obscode=807, eph_mode="N")
|
|
93
|
+
# Check that it returned the right sort of array.
|
|
94
|
+
self.assertEqual(
|
|
95
|
+
oorb_ephs.shape,
|
|
96
|
+
(len(self.ephems.oorb_elem), len(times), self.len_ephems_full),
|
|
97
|
+
)
|
|
98
|
+
|
|
99
|
+
def test_ephemeris(self):
|
|
100
|
+
# Calculate and convert ephemerides.
|
|
101
|
+
self.ephems.set_orbits(self.orbits)
|
|
102
|
+
times = np.arange(49353, 49353 + 2, 0.3)
|
|
103
|
+
eph_times = self.ephems._convert_times(times)
|
|
104
|
+
oorb_ephs = self.ephems._generate_oorb_ephs_basic(eph_times, obscode=807)
|
|
105
|
+
# Group by object, and check grouping.
|
|
106
|
+
ephs = self.ephems._convert_oorb_ephs_basic(oorb_ephs, by_object=True)
|
|
107
|
+
self.assertEqual(len(ephs), len(self.orbits))
|
|
108
|
+
# Group by time, and check grouping.
|
|
109
|
+
oorb_ephs = self.ephems._generate_oorb_ephs_basic(eph_times, obscode=807)
|
|
110
|
+
ephs = self.ephems._convert_oorb_ephs_basic(oorb_ephs, by_object=False)
|
|
111
|
+
self.assertEqual(len(ephs), len(times))
|
|
112
|
+
# And test all-wrapped-up method:
|
|
113
|
+
ephs_all = self.ephems.generate_ephemerides(
|
|
114
|
+
times,
|
|
115
|
+
obscode=807,
|
|
116
|
+
eph_mode="N",
|
|
117
|
+
eph_type="basic",
|
|
118
|
+
time_scale="UTC",
|
|
119
|
+
by_object=False,
|
|
120
|
+
)
|
|
121
|
+
# See https://rubinobs.atlassian.net/browse/SP-1633
|
|
122
|
+
# This needs to be fixed, but on a separate ticket
|
|
123
|
+
# for key in ephs_all.dtype.names:
|
|
124
|
+
# np.testing.assert_almost_equal(ephs_all[key], ephs[key])
|
|
125
|
+
|
|
126
|
+
# Reset ephems to use KEP Orbits, and calculate new ephemerides.
|
|
127
|
+
self.ephems.set_orbits(self.orbits_kep)
|
|
128
|
+
oorb_ephs = self.ephems._generate_oorb_ephs_basic(eph_times, obscode=807, eph_mode="N")
|
|
129
|
+
ephs_kep = self.ephems._convert_oorb_ephs_basic(oorb_ephs, by_object=True)
|
|
130
|
+
self.assertEqual(len(ephs_kep), len(self.orbits_kep))
|
|
131
|
+
oorb_ephs = self.ephems._generate_oorb_ephs_basic(eph_times, obscode=807, eph_mode="N")
|
|
132
|
+
ephs_kep = self.ephems._convert_oorb_ephs_basic(oorb_ephs, by_object=False)
|
|
133
|
+
self.assertEqual(len(ephs_kep), len(times))
|
|
134
|
+
# And test all-wrapped-up method:
|
|
135
|
+
ephs_all_kep = self.ephems.generate_ephemerides(
|
|
136
|
+
times,
|
|
137
|
+
obscode=807,
|
|
138
|
+
eph_mode="N",
|
|
139
|
+
eph_type="basic",
|
|
140
|
+
time_scale="UTC",
|
|
141
|
+
by_object=False,
|
|
142
|
+
)
|
|
143
|
+
# Also https://rubinobs.atlassian.net/browse/SP-1633
|
|
144
|
+
# for key in ephs_all_kep.dtype.names:
|
|
145
|
+
# np.testing.assert_almost_equal(ephs_all_kep[key], ephs_kep[key])
|
|
146
|
+
|
|
147
|
+
# Check that ephemerides calculated from the different (COM/KEP)
|
|
148
|
+
# orbits are almost equal
|
|
149
|
+
for column in ephs.dtype.names:
|
|
150
|
+
np.testing.assert_allclose(ephs[column], ephs_kep[column], rtol=1e-5, atol=1e-4)
|
|
151
|
+
# Check that the wrapped method using KEP elements and the wrapped
|
|
152
|
+
# method using COM elements match.
|
|
153
|
+
for column in ephs_all.dtype.names:
|
|
154
|
+
np.testing.assert_allclose(ephs_all_kep[column], ephs_all[column], rtol=1e-5, atol=1e-4)
|
|
155
|
+
|
|
156
|
+
|
|
157
|
+
@unittest.skip("Temporary skip until ephemerides replaced")
|
|
158
|
+
class TestJPLValues(unittest.TestCase):
|
|
159
|
+
"""Test the oorb generated RA/Dec values against
|
|
160
|
+
JPL generated RA/Dec values."""
|
|
161
|
+
|
|
162
|
+
def setUp(self):
|
|
163
|
+
# Read orbits.
|
|
164
|
+
self.orbits = Orbits()
|
|
165
|
+
self.jpl_dir = os.path.join(get_data_dir(), "tests", "jpl_testdata")
|
|
166
|
+
self.orbits.read_orbits(os.path.join(self.jpl_dir, "S0_n747.des"), skiprows=1)
|
|
167
|
+
# Read JPL ephems.
|
|
168
|
+
self.jpl = pd.read_csv(os.path.join(self.jpl_dir, "807_n747.txt"), sep=r"\s+")
|
|
169
|
+
# Temp key fix
|
|
170
|
+
self.jpl["obj_id"] = self.jpl["objId"]
|
|
171
|
+
# Add times in TAI and UTC, because.
|
|
172
|
+
t = Time(self.jpl["epoch_mjd"], format="mjd", scale="utc")
|
|
173
|
+
self.jpl["mjdTAI"] = t.tai.mjd
|
|
174
|
+
self.jpl["mjdUTC"] = t.utc.mjd
|
|
175
|
+
|
|
176
|
+
def tear_down(self):
|
|
177
|
+
del self.orbits
|
|
178
|
+
del self.jpl
|
|
179
|
+
|
|
180
|
+
def test_ra_dec(self):
|
|
181
|
+
# We won't compare Vmag, because this also needs information
|
|
182
|
+
# on trailing losses.
|
|
183
|
+
times = self.jpl["mjdUTC"].unique()
|
|
184
|
+
delta_ra = np.zeros(len(times), float)
|
|
185
|
+
delta_dec = np.zeros(len(times), float)
|
|
186
|
+
for i, t in enumerate(times):
|
|
187
|
+
# Find the JPL obj_ids visible at this time.
|
|
188
|
+
j = self.jpl.query("mjdUTC == @t").sort_values("obj_id")
|
|
189
|
+
# Set the ephems, using the objects seen at this time.
|
|
190
|
+
suborbits = self.orbits.orbits.query("obj_id in @j.obj_id").sort_values("obj_id")
|
|
191
|
+
sub_orbits = Orbits()
|
|
192
|
+
sub_orbits.set_orbits(suborbits)
|
|
193
|
+
ephems = PyOrbEphemerides()
|
|
194
|
+
ephems.set_orbits(sub_orbits)
|
|
195
|
+
ephs = ephems.generate_ephemerides(
|
|
196
|
+
[t],
|
|
197
|
+
time_scale="UTC",
|
|
198
|
+
obscode=807,
|
|
199
|
+
eph_mode="N",
|
|
200
|
+
eph_type="Basic",
|
|
201
|
+
by_object=False,
|
|
202
|
+
)
|
|
203
|
+
delta_ra[i] = np.abs(ephs["ra"] - j["ra_deg"].values).max()
|
|
204
|
+
delta_dec[i] = np.abs(ephs["dec"] - j["dec_deg"].values).max()
|
|
205
|
+
# Convert to mas
|
|
206
|
+
delta_ra *= 3600.0 * 1000.0
|
|
207
|
+
delta_dec *= 3600.0 * 1000.0
|
|
208
|
+
# Much of the time we're closer than 1mas,
|
|
209
|
+
# but there are a few which hit higher values.
|
|
210
|
+
print("max JPL errors", np.max(delta_ra), np.max(delta_dec))
|
|
211
|
+
print("std JPL errors", np.std(delta_ra), np.std(delta_dec))
|
|
212
|
+
self.assertLess(np.max(delta_ra), 25)
|
|
213
|
+
self.assertLess(np.max(delta_dec), 25)
|
|
214
|
+
self.assertLess(np.std(delta_ra), 3)
|
|
215
|
+
self.assertLess(np.std(delta_dec), 3)
|
|
216
|
+
|
|
217
|
+
|
|
218
|
+
if __name__ == "__main__":
|
|
219
|
+
unittest.main()
|
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
import os
|
|
2
|
+
import unittest
|
|
3
|
+
|
|
4
|
+
import numpy as np
|
|
5
|
+
import pandas as pd
|
|
6
|
+
from pandas.testing import assert_frame_equal
|
|
7
|
+
from rubin_scheduler.data import get_data_dir
|
|
8
|
+
|
|
9
|
+
from rubin_sim.moving_objects import Orbits
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class TestOrbits(unittest.TestCase):
|
|
13
|
+
def setUp(self):
|
|
14
|
+
self.testdir = os.path.join(get_data_dir(), "tests", "orbits_testdata")
|
|
15
|
+
|
|
16
|
+
def test_equal_not_equal(self):
|
|
17
|
+
orbits = Orbits()
|
|
18
|
+
orbits.read_orbits(os.path.join(self.testdir, "test_orbitsQ.des"))
|
|
19
|
+
self.assertEqual(len(orbits), 4)
|
|
20
|
+
orbits2 = Orbits()
|
|
21
|
+
orbits2.read_orbits(os.path.join(self.testdir, "test_orbitsQ.des"))
|
|
22
|
+
self.assertEqual(orbits, orbits2)
|
|
23
|
+
orbits3 = Orbits()
|
|
24
|
+
orbits3.read_orbits(os.path.join(self.testdir, "test_orbitsA.des"))
|
|
25
|
+
self.assertNotEqual(orbits, orbits3)
|
|
26
|
+
|
|
27
|
+
def test_iteration_and_indexing(self):
|
|
28
|
+
orbits = Orbits()
|
|
29
|
+
orbits.read_orbits(os.path.join(self.testdir, "test_orbitsNEO.s3m"))
|
|
30
|
+
orbits_single = orbits[0]
|
|
31
|
+
assert_frame_equal(orbits_single.orbits, orbits.orbits.query("index==0"))
|
|
32
|
+
orbits_single = orbits[3]
|
|
33
|
+
assert_frame_equal(orbits_single.orbits, orbits.orbits.query("index==3"))
|
|
34
|
+
# Test iteration through all orbits.
|
|
35
|
+
for orb, (i, orbi) in zip(orbits, orbits.orbits.iterrows()):
|
|
36
|
+
self.assertEqual(orb.orbits.obj_id.values[0], orbi.obj_id)
|
|
37
|
+
self.assertTrue(isinstance(orb, Orbits))
|
|
38
|
+
self.assertEqual(orb.orbits.index, i)
|
|
39
|
+
# Test iteration through a subset of orbits.
|
|
40
|
+
orbits_sub = Orbits()
|
|
41
|
+
orbits_sub.set_orbits(orbits.orbits.query("index > 4"))
|
|
42
|
+
for orb, (i, orbi) in zip(orbits_sub, orbits_sub.orbits.iterrows()):
|
|
43
|
+
self.assertEqual(orb.orbits.obj_id.values[0], orbi.obj_id)
|
|
44
|
+
self.assertTrue(isinstance(orb, Orbits))
|
|
45
|
+
self.assertEqual(orb.orbits.index, i)
|
|
46
|
+
|
|
47
|
+
def test_slicing(self):
|
|
48
|
+
"""
|
|
49
|
+
Test that we can slice a collection of orbits
|
|
50
|
+
"""
|
|
51
|
+
orbits = Orbits()
|
|
52
|
+
orbits.read_orbits(os.path.join(self.testdir, "test_orbitsNEO.s3m"))
|
|
53
|
+
orbit_slice = orbits[2:6]
|
|
54
|
+
self.assertEqual(orbit_slice[0], orbits[2])
|
|
55
|
+
self.assertEqual(orbit_slice[1], orbits[3])
|
|
56
|
+
self.assertEqual(orbit_slice[2], orbits[4])
|
|
57
|
+
self.assertEqual(orbit_slice[3], orbits[5])
|
|
58
|
+
self.assertEqual(len(orbit_slice), 4)
|
|
59
|
+
|
|
60
|
+
orbit_slice = orbits[1:7:2]
|
|
61
|
+
self.assertEqual(orbit_slice[0], orbits[1])
|
|
62
|
+
self.assertEqual(orbit_slice[1], orbits[3])
|
|
63
|
+
self.assertEqual(orbit_slice[2], orbits[5])
|
|
64
|
+
self.assertEqual(len(orbit_slice), 3)
|
|
65
|
+
|
|
66
|
+
def test_offset_dataframe(self):
|
|
67
|
+
"""
|
|
68
|
+
Test that we can slice and iterate through an orbits
|
|
69
|
+
dataframe that has already been sub-selected from another
|
|
70
|
+
dataframe.
|
|
71
|
+
"""
|
|
72
|
+
orbits0 = Orbits()
|
|
73
|
+
orbits0.read_orbits(os.path.join(self.testdir, "test_orbitsNEO.s3m"))
|
|
74
|
+
|
|
75
|
+
orbits_sub = Orbits()
|
|
76
|
+
orbits_sub.set_orbits(orbits0.orbits.query("index>1"))
|
|
77
|
+
|
|
78
|
+
self.assertEqual(len(orbits_sub), 6)
|
|
79
|
+
|
|
80
|
+
orbit_slice = orbits_sub[2:6]
|
|
81
|
+
self.assertEqual(orbit_slice[0], orbits_sub[2])
|
|
82
|
+
self.assertEqual(orbit_slice[1], orbits_sub[3])
|
|
83
|
+
self.assertEqual(orbit_slice[2], orbits_sub[4])
|
|
84
|
+
self.assertEqual(orbit_slice[3], orbits_sub[5])
|
|
85
|
+
self.assertEqual(len(orbit_slice), 4)
|
|
86
|
+
|
|
87
|
+
orbit_slice = orbits_sub[1:5:2]
|
|
88
|
+
self.assertEqual(orbit_slice[0], orbits_sub[1])
|
|
89
|
+
self.assertEqual(orbit_slice[1], orbits_sub[3])
|
|
90
|
+
self.assertEqual(len(orbit_slice), 2)
|
|
91
|
+
|
|
92
|
+
for ii, oo in enumerate(orbits_sub):
|
|
93
|
+
self.assertEqual(oo, orbits0[ii + 2])
|
|
94
|
+
|
|
95
|
+
def test_read_orbits(self):
|
|
96
|
+
orbits = Orbits()
|
|
97
|
+
orbits.read_orbits(os.path.join(self.testdir, "test_orbitsQ.des"))
|
|
98
|
+
self.assertEqual(len(orbits), 4)
|
|
99
|
+
orbits.read_orbits(os.path.join(self.testdir, "test_orbitsA.des"))
|
|
100
|
+
self.assertEqual(len(orbits), 4)
|
|
101
|
+
orbits.read_orbits(os.path.join(self.testdir, "test_orbitsCAR.des"))
|
|
102
|
+
self.assertEqual(len(orbits), 1)
|
|
103
|
+
with self.assertRaises(ValueError):
|
|
104
|
+
orbits.read_orbits(os.path.join(self.testdir, "test_orbitsBadMix.des"))
|
|
105
|
+
with self.assertRaises(ValueError):
|
|
106
|
+
orbits.read_orbits(os.path.join(self.testdir, "test_orbitsBad.des"))
|
|
107
|
+
|
|
108
|
+
def test_set_orbits(self):
|
|
109
|
+
orbits = Orbits()
|
|
110
|
+
orbits.read_orbits(os.path.join(self.testdir, "test_orbitsQ.des"))
|
|
111
|
+
# Test that we can set the orbits using a dataframe.
|
|
112
|
+
suborbits = orbits.orbits.head(1)
|
|
113
|
+
new_orbits = Orbits()
|
|
114
|
+
new_orbits.set_orbits(suborbits)
|
|
115
|
+
self.assertEqual(len(new_orbits), 1)
|
|
116
|
+
self.assertEqual(new_orbits.orb_format, "COM")
|
|
117
|
+
assert_frame_equal(new_orbits.orbits, suborbits)
|
|
118
|
+
# Test that we can set the orbits using a Series.
|
|
119
|
+
for i, sso in suborbits.iterrows():
|
|
120
|
+
new_orbits = Orbits()
|
|
121
|
+
new_orbits.set_orbits(sso)
|
|
122
|
+
self.assertEqual(len(new_orbits), 1)
|
|
123
|
+
self.assertEqual(new_orbits.orb_format, "COM")
|
|
124
|
+
assert_frame_equal(new_orbits.orbits, suborbits)
|
|
125
|
+
# Test that we can set the orbits using a numpy array of many objects.
|
|
126
|
+
numpyorbits = orbits.orbits.to_records(index=False)
|
|
127
|
+
new_orbits = Orbits()
|
|
128
|
+
new_orbits.set_orbits(numpyorbits)
|
|
129
|
+
self.assertEqual(len(new_orbits), len(orbits))
|
|
130
|
+
self.assertEqual(new_orbits.orb_format, "COM")
|
|
131
|
+
assert_frame_equal(new_orbits.orbits, orbits.orbits)
|
|
132
|
+
# And test that this works for a single row of the numpy array.
|
|
133
|
+
onenumpyorbits = numpyorbits[0]
|
|
134
|
+
new_orbits = Orbits()
|
|
135
|
+
new_orbits.set_orbits(onenumpyorbits)
|
|
136
|
+
self.assertEqual(len(new_orbits), 1)
|
|
137
|
+
self.assertEqual(new_orbits.orb_format, "COM")
|
|
138
|
+
assert_frame_equal(new_orbits.orbits, suborbits)
|
|
139
|
+
# And test that it fails appropriately when columns are not correct.
|
|
140
|
+
neworbits = pd.DataFrame(orbits.orbits)
|
|
141
|
+
newcols = neworbits.columns.values.tolist()
|
|
142
|
+
newcols[0] = "ssmId"
|
|
143
|
+
newcols[3] = "ecc"
|
|
144
|
+
neworbits.columns = newcols
|
|
145
|
+
new_orbits = Orbits()
|
|
146
|
+
with self.assertRaises(ValueError):
|
|
147
|
+
new_orbits.set_orbits(neworbits)
|
|
148
|
+
|
|
149
|
+
def test_set_seds(self):
|
|
150
|
+
"""
|
|
151
|
+
Test that the self-assignment of SEDs works as expected.
|
|
152
|
+
"""
|
|
153
|
+
orbits = Orbits()
|
|
154
|
+
# Test with a range of a values.
|
|
155
|
+
a = np.arange(0, 5, 0.05)
|
|
156
|
+
orbs = pd.DataFrame(a, columns=["a"])
|
|
157
|
+
seds = orbits.assign_sed(orbs)
|
|
158
|
+
self.assertEqual(np.unique(seds[np.where(a < 2)]), "S.dat")
|
|
159
|
+
self.assertEqual(np.unique(seds[np.where(a > 4)]), "C.dat")
|
|
160
|
+
# Test when read a values.
|
|
161
|
+
orbits.read_orbits(os.path.join(self.testdir, "test_orbitsA.des"))
|
|
162
|
+
sedvals = orbits.assign_sed(orbits.orbits, random_seed=42)
|
|
163
|
+
orbits2 = Orbits()
|
|
164
|
+
orbits2.read_orbits(os.path.join(self.testdir, "test_orbitsQ.des"))
|
|
165
|
+
sedvals2 = orbits2.assign_sed(orbits2.orbits, random_seed=42)
|
|
166
|
+
np.testing.assert_array_equal(sedvals, sedvals2)
|
|
167
|
+
|
|
168
|
+
|
|
169
|
+
if __name__ == "__main__":
|
|
170
|
+
unittest.main()
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import os
|
|
2
|
+
import unittest
|
|
3
|
+
|
|
4
|
+
from rubin_scheduler.data import get_data_dir
|
|
5
|
+
|
|
6
|
+
import rubin_sim.phot_utils as phot_utils
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class SedDataUnitTest(unittest.TestCase):
|
|
10
|
+
|
|
11
|
+
def setUp(self) -> None:
|
|
12
|
+
# Read the lsst bandpasses
|
|
13
|
+
lsst = {}
|
|
14
|
+
lsst_filterlist = "ugrizy"
|
|
15
|
+
for b in lsst_filterlist:
|
|
16
|
+
lsst[b] = phot_utils.Bandpass()
|
|
17
|
+
lsst[b].read_throughput(os.path.join(get_data_dir(), "throughputs", "baseline", f"total_{b}.dat"))
|
|
18
|
+
self.lsst = lsst
|
|
19
|
+
|
|
20
|
+
def test_sun(self) -> None:
|
|
21
|
+
sun = phot_utils.Sed()
|
|
22
|
+
sun.read_sed_flambda(os.path.join(get_data_dir(), "movingObjects", "kurucz_sun.gz"))
|
|
23
|
+
expected_mags = {"u": -25.3, "g": -26.5, "r": -27.0, "i": -27.0, "z": -27.1, "y": -27.1}
|
|
24
|
+
for b in "ugrizy":
|
|
25
|
+
mag = sun.calc_mag(self.lsst[b])
|
|
26
|
+
self.assertTrue(abs(mag - expected_mags[b]) < 0.2)
|
|
27
|
+
|
|
28
|
+
def test_seds(self):
|
|
29
|
+
# We have some sample asteroid spectra in rubin_sim_data_dir -
|
|
30
|
+
# However, those are 'observed' spectra
|
|
31
|
+
# (already includes a sample solar spectra)
|
|
32
|
+
ast_templates = [
|
|
33
|
+
k.replace(".dat.gz", "")
|
|
34
|
+
for k in os.listdir(os.path.join(get_data_dir(), "movingObjects"))
|
|
35
|
+
if "kurucz" not in k and "harris" not in k
|
|
36
|
+
]
|
|
37
|
+
# Read the sso seds from disk (using rubin_sim.photUtils.Sed)
|
|
38
|
+
sso = {}
|
|
39
|
+
for k in ast_templates:
|
|
40
|
+
sso[k] = phot_utils.Sed()
|
|
41
|
+
sso[k].read_sed_flambda(os.path.join(get_data_dir(), "movingObjects", f"{k}.dat.gz"))
|
|
42
|
+
|
|
43
|
+
# Calculate the colors for each type:
|
|
44
|
+
# referenc e bandpass first
|
|
45
|
+
refband_name = "r"
|
|
46
|
+
refband = self.lsst[refband_name]
|
|
47
|
+
# Calculate the reference bandpass magnitudes
|
|
48
|
+
refmags = {}
|
|
49
|
+
for k in sso:
|
|
50
|
+
refmags[k] = sso[k].calc_mag(refband)
|
|
51
|
+
|
|
52
|
+
# And now the colors
|
|
53
|
+
colors = {}
|
|
54
|
+
for k in sso:
|
|
55
|
+
colors[k] = {}
|
|
56
|
+
for f in "ugrizy":
|
|
57
|
+
colors[k][f"lsst_{f}"] = sso[k].calc_mag(self.lsst[f]) - refmags[k]
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
if __name__ == "__main__":
|
|
61
|
+
unittest.main()
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Module to test that Approximate Bandpasses are in sync with the official LSST
|
|
3
|
+
Bandpasses from SYSENG
|
|
4
|
+
|
|
5
|
+
Note: While the LSST bandpasses list throughput values corresponding to
|
|
6
|
+
wavelengths in the range of 300.0-1150.0 nm, the `approximate_baseline`
|
|
7
|
+
directory of throughputs is created by a script manually. It is thus possible
|
|
8
|
+
for this directory to fall out of sync with the SYSENG values in `baseline`.
|
|
9
|
+
This module is intended to test whether this is happening.
|
|
10
|
+
"""
|
|
11
|
+
|
|
12
|
+
import os
|
|
13
|
+
import unittest
|
|
14
|
+
|
|
15
|
+
import numpy as np
|
|
16
|
+
from rubin_scheduler.data import get_data_dir
|
|
17
|
+
|
|
18
|
+
from rubin_sim.phot_utils import Bandpass, PhotometricParameters
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
class ApproximateBandPassTest(unittest.TestCase):
|
|
22
|
+
"""
|
|
23
|
+
Tests for the approximate Bandpasses in the throughputs directory
|
|
24
|
+
"""
|
|
25
|
+
|
|
26
|
+
long_message = True
|
|
27
|
+
|
|
28
|
+
def setUp(self):
|
|
29
|
+
"""Setup before tests."""
|
|
30
|
+
throughputs_dir = os.path.join(get_data_dir(), "throughputs")
|
|
31
|
+
self.approx_band_pass_dir = os.path.join(throughputs_dir, "approximate_baseline")
|
|
32
|
+
self.approx_band_pass_dict = {}
|
|
33
|
+
for kk in ["u", "g", "r", "i", "z", "y"]:
|
|
34
|
+
self.approx_band_pass_dict[kk] = Bandpass()
|
|
35
|
+
self.approx_band_pass_dict[kk].read_throughput(
|
|
36
|
+
os.path.join(self.approx_band_pass_dir, f"total_{kk}.dat")
|
|
37
|
+
)
|
|
38
|
+
self.ref_band_pass_dir = os.path.join(throughputs_dir, "baseline")
|
|
39
|
+
self.ref_band_pass_dict = {}
|
|
40
|
+
for kk in ["u", "g", "r", "i", "z", "y"]:
|
|
41
|
+
self.ref_band_pass_dict[kk] = Bandpass()
|
|
42
|
+
self.ref_band_pass_dict[kk].read_throughput(
|
|
43
|
+
os.path.join(self.ref_band_pass_dir, f"total_{kk}.dat")
|
|
44
|
+
)
|
|
45
|
+
self.error_msg = "The failure of this test indicates that the"
|
|
46
|
+
" approximate bandpasses in the lsst throughputs directory do not"
|
|
47
|
+
"sync up with the baseline bandpasses is throughputs. "
|
|
48
|
+
" This may require running the script :"
|
|
49
|
+
" throughputs.approximate_baseline/approximateBandpasses.py"
|
|
50
|
+
|
|
51
|
+
def test_band_pass_integrals(self):
|
|
52
|
+
"""Test that the ratio of the quantity
|
|
53
|
+
int dlambda T(lambda) = band flux for a SED proportional to $lambda$
|
|
54
|
+
for the approximate bandpasses to the SYSENG band passes is 1.0 to an
|
|
55
|
+
absolute tolerance hard coded to be 1.0e-4
|
|
56
|
+
|
|
57
|
+
"""
|
|
58
|
+
phot_params = PhotometricParameters()
|
|
59
|
+
|
|
60
|
+
for bn in "ugrizy":
|
|
61
|
+
ref_band_pass = self.ref_band_pass_dict[bn]
|
|
62
|
+
approx_band_pass = self.approx_band_pass_dict[bn]
|
|
63
|
+
|
|
64
|
+
zp_ref = ref_band_pass.calc_zp_t(phot_params)
|
|
65
|
+
zp_approx = approx_band_pass.calc_zp_t(phot_params)
|
|
66
|
+
self.assertAlmostEqual(zp_ref, zp_approx, delta=1.0e-4, msg=self.error_msg)
|
|
67
|
+
|
|
68
|
+
def test_bandpasses_indiv(self):
|
|
69
|
+
"""
|
|
70
|
+
Test that individual transmission values at wavelengths kept in the
|
|
71
|
+
approximate bandpasses match the individual transmission values in
|
|
72
|
+
the reference bandpasses
|
|
73
|
+
"""
|
|
74
|
+
for bn in "ugrizy":
|
|
75
|
+
approx_band_pass = self.approx_band_pass_dict[bn]
|
|
76
|
+
ref_band_pass = self.ref_band_pass_dict[bn]
|
|
77
|
+
refwavelen = ref_band_pass.wavelen
|
|
78
|
+
approxwavelen = approx_band_pass.wavelen
|
|
79
|
+
mask = np.zeros(len(refwavelen), dtype=bool)
|
|
80
|
+
for i, wave in enumerate(refwavelen):
|
|
81
|
+
if wave in approxwavelen:
|
|
82
|
+
mask[i] = True
|
|
83
|
+
# Assume that the wavelengths are in order
|
|
84
|
+
np.testing.assert_array_almost_equal(ref_band_pass.sb[mask], approx_band_pass.sb, decimal=3)
|
|
85
|
+
|
|
86
|
+
def tearDown(self):
|
|
87
|
+
pass
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
if __name__ == "__main__":
|
|
91
|
+
unittest.main()
|