From b4bdc7e0b0b8bab782b0107d495cbdb28e5d7e3d Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 5 Oct 2026 18:32:18 +0000 Subject: [PATCH 1/2] [pre-commit.ci] pre-commit autoupdate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit updates: - [github.com/astral-sh/ruff-pre-commit: v0.15.2 → v0.16.10](https://github.com/astral-sh/ruff-pre-commit/compare/v0.15.2...v0.16.10) --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 136a830a..1392d485 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -20,7 +20,7 @@ repos: | docs/.*\.(svg|png)$ # documentation images ) - repo: https://github.com/astral-sh/ruff-pre-commit - rev: "v0.15.2" + rev: "v0.16.10" hooks: - id: ruff-check args: [--fix] From dca55e677668dcfb4a4a37436a78a1d0d41da539 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 5 Oct 2026 18:40:59 +0000 Subject: [PATCH 2/2] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- docs/swapi/figure_src/figure_utils.py | 73 +- .../figure_src/plot_alpha_peak_finding.py | 15 +- .../figure_src/plot_calibration_curves.py | 2 +- .../plot_collapsed_response_grid.py | 10 +- docs/swapi/figure_src/plot_fit_accuracy.py | 39 +- .../figure_src/plot_passband_boundaries.py | 6 +- .../figure_src/plot_pui_cutoff_staircase.py | 66 +- .../swapi/figure_src/plot_pui_distribution.py | 5 +- .../plot_pui_reference_comparison.py | 43 +- docs/swapi/figure_src/plot_real_data_fit.py | 46 +- docs/swapi/figure_src/plot_spectra.py | 15 +- docs/swapi/figure_src/plot_uncertainty_mc.py | 36 +- .../figure_src/plot_validation_scatter.py | 26 +- imap_l3_data_processor.py | 162 +- imap_l3_processing/cdf/cdf_utils.py | 67 +- .../cdf/imap_attribute_manager.py | 50 +- .../codice/l3/hi/codice_hi_processor.py | 230 +- ...odice_hi_l3a_direct_events_dependencies.py | 53 +- .../codice_hi_mass_correction_lookup_table.py | 17 +- imap_l3_processing/codice/l3/hi/models.py | 183 +- .../codice_pitch_angle_dependencies.py | 27 +- ...odice_lo_l3a_direct_events_dependencies.py | 99 +- ...e_lo_l3a_partial_densities_dependencies.py | 49 +- .../lo/codice_lo_l3a_ratios_dependencies.py | 10 +- ...ce_lo_l3b_3d_distributions_dependencies.py | 98 +- .../codice/l3/lo/codice_lo_processor.py | 458 ++- imap_l3_processing/codice/l3/lo/constants.py | 2 +- .../lo/direct_events/science/angle_lookup.py | 29 +- .../science/efficiency_lookup.py | 13 +- .../lo/direct_events/science/energy_lookup.py | 12 +- .../science/geometric_factor_lookup.py | 134 +- .../science/mass_coefficient_lookup.py | 2 +- .../science/mass_species_bin_lookup.py | 12 +- imap_l3_processing/codice/l3/lo/models.py | 331 +- .../l3/lo/science/codice_lo_calculations.py | 247 +- imap_l3_processing/codice/quality_flags.py | 4 +- imap_l3_processing/constants.py | 26 +- imap_l3_processing/data_utils.py | 39 +- imap_l3_processing/glows/descriptors.py | 14 +- imap_l3_processing/glows/glows_processor.py | 600 +++- .../glows/l3a/glows_l3a_dependencies.py | 45 +- .../glows/l3a/glows_toolkit/ccsds.py | 85 +- .../glows/l3a/glows_toolkit/constants.py | 32 +- .../glows_toolkit/constants_arch20241201.py | 29 +- .../glows/l3a/glows_toolkit/direct_event.py | 35 +- .../glows/l3a/glows_toolkit/funcs.py | 67 +- .../geom_fun_libr_box/__init__.py | 193 +- .../glows/l3a/glows_toolkit/imap_time.py | 5 +- .../glows_toolkit/l0_data_direct_events.py | 39 +- .../l3a/glows_toolkit/l0_data_histogram.py | 61 +- .../glows_toolkit/l1a_data_direct_events.py | 252 +- .../l3a/glows_toolkit/l1a_data_histogram.py | 150 +- .../glows_toolkit/l1b_data_direct_events.py | 225 +- .../l3a/glows_toolkit/l1b_data_histogram.py | 846 +++-- .../l3a/glows_toolkit/l2_data_histogram.py | 579 ++-- .../glows/l3a/glows_toolkit/l3a_data.py | 439 ++- .../glows/l3a/glows_toolkit/reader.py | 36 +- .../glows/l3a/glows_toolkit/time.py | 3 + imap_l3_processing/glows/l3a/models.py | 105 +- .../science/bad_angle_flag_configuration.py | 15 +- .../l3a/science/calculate_daily_lightcurve.py | 54 +- ...ime_independent_background_lookup_table.py | 23 +- imap_l3_processing/glows/l3a/utils.py | 279 +- ...annot_process_carrington_rotation_error.py | 1 - .../glows/l3bc/dependency_validator.py | 58 +- .../glows/l3bc/glows_l3bc_dependencies.py | 33 +- .../glows/l3bc/glows_l3bc_initializer.py | 171 +- .../glows/l3bc/l3bc_toolkit/constants.py | 45 +- .../glows/l3bc/l3bc_toolkit/funcs.py | 857 +++-- .../l3bc_toolkit/l3b_CarringtonIonRate.py | 346 +- .../l3bc/l3bc_toolkit/l3b_DailyIonRate.py | 304 +- .../l3bc_toolkit/l3c_CarringtonSolarWind.py | 212 +- .../l3bc_toolkit/l3c_EclipticSolarWind.py | 102 +- imap_l3_processing/glows/l3bc/models.py | 210 +- .../glows/l3bc/science/filter_out_bad_days.py | 32 +- .../glows/l3bc/science/generate_l3bc.py | 75 +- imap_l3_processing/glows/l3bc/utils.py | 63 +- .../glows/l3d/glows_l3d_dependencies.py | 95 +- .../glows/l3d/glows_l3d_initializer.py | 140 +- imap_l3_processing/glows/l3d/models.py | 18 +- .../glows/l3d/science/generate_l3d.py | 51 +- .../glows/l3d/science/toolkit/constants.py | 45 +- .../glows/l3d/science/toolkit/funcs.py | 857 +++-- .../science/toolkit/l3d_SolarParamHistory.py | 729 ++-- imap_l3_processing/glows/l3d/utils.py | 158 +- .../glows/l3e/glows_l3e_call_arguments.py | 5 +- .../glows/l3e/glows_l3e_dependencies.py | 150 +- .../glows/l3e/glows_l3e_hi_model.py | 99 +- .../glows/l3e/glows_l3e_initializer.py | 65 +- .../glows/l3e/glows_l3e_lo_model.py | 68 +- .../glows/l3e/glows_l3e_ultra_model.py | 67 +- .../glows/l3e/glows_l3e_utils.py | 258 +- .../glows/l3e/reprocess_info.py | 29 +- imap_l3_processing/glows/quality_flags.py | 7 +- .../hi/hi_combined_initializer.py | 76 +- .../hi/hi_combined_sensor_dependencies.py | 29 +- imap_l3_processing/hi/hi_processor.py | 202 +- imap_l3_processing/hi/hi_sp_initializer.py | 88 +- .../hi/hi_spectral_fit_dependencies.py | 23 +- imap_l3_processing/hi/utils.py | 71 +- .../hit/l3/hit_l3_sectored_dependencies.py | 23 +- imap_l3_processing/hit/l3/hit_processor.py | 394 ++- imap_l3_processing/hit/l3/models.py | 9 +- .../hit/l3/pha/hit_l3_pha_dependencies.py | 135 +- .../hit/l3/pha/pha_event_reader.py | 85 +- .../hit/l3/pha/science/calculate_pha.py | 176 +- .../science/cosine_correction_lookup_table.py | 75 +- .../l3/pha/science/hit_event_type_lookup.py | 31 +- .../hit/l3/pha/science/range_fit_lookup.py | 36 +- .../hit/l3/sectored_products/models.py | 281 +- .../science/sectored_products_algorithms.py | 17 +- imap_l3_processing/hit/l3/utils.py | 3 +- imap_l3_processing/hit/quality_flags.py | 4 +- .../lo/l3/lo_combined_dependencies.py | 10 +- .../lo/l3/lo_l3_spectral_fit_dependencies.py | 9 +- imap_l3_processing/lo/l3/lo_sp_initializer.py | 34 +- imap_l3_processing/lo/lo_processor.py | 159 +- .../lo/lo_txt_to_cdf_converter_spike.py | 252 +- .../maps/hilo_l3_survival_dependencies.py | 101 +- imap_l3_processing/maps/map_combination.py | 217 +- imap_l3_processing/maps/map_descriptors.py | 120 +- imap_l3_processing/maps/map_initializer.py | 64 +- imap_l3_processing/maps/map_models.py | 319 +- imap_l3_processing/maps/map_processor.py | 7 +- imap_l3_processing/maps/mpfit.py | 1965 ++++++----- imap_l3_processing/maps/quality_flags.py | 2 +- .../maps/rectangular_survival_probability.py | 200 +- imap_l3_processing/maps/sp_map_initializer.py | 94 +- imap_l3_processing/maps/spectral_fit.py | 144 +- .../maps/survival_probability_processing.py | 104 +- imap_l3_processing/models.py | 19 +- imap_l3_processing/pitch_angles.py | 184 +- .../predicted_ephemeris_tracker.py | 4 +- imap_l3_processing/processor.py | 17 +- imap_l3_processing/swapi/constants.py | 4 +- imap_l3_processing/swapi/l3a/chunk_fits.py | 20 +- imap_l3_processing/swapi/l3a/models.py | 58 +- .../pickup_ion/calculate_pickup_ion_values.py | 2 +- .../pickup_ion/collapsed_response_grid.py | 45 +- .../density_of_neutral_helium_lookup_table.py | 15 +- .../l3a/science/pickup_ion/goodness_of_fit.py | 11 +- .../l3a/science/pickup_ion/inflow_vector.py | 6 +- .../swapi/l3a/science/pickup_ion/moments.py | 1 + .../swapi/l3a/science/pickup_ion/utils.py | 3 +- .../vasyliunas_siscoe_distribution.py | 27 +- .../alpha/calculate_initial_guess.py | 4 +- .../alpha/fit_solar_wind_alpha_model.py | 28 +- .../l3a/science/solar_wind/forward_model.py | 33 +- .../science/solar_wind/integration_limits.py | 14 +- .../proton/calculate_initial_guess.py | 16 +- .../solar_wind/proton/escape_local_minimum.py | 1 - .../proton/fit_solar_wind_proton_model.py | 12 +- .../optimize_solar_wind_proton_params.py | 4 +- .../science/solar_wind/trim_open_aperture.py | 31 +- .../swapi/l3a/science/uncertainties.py | 8 +- .../swapi/l3a/swapi_l3a_dependencies.py | 92 +- imap_l3_processing/swapi/l3a/utils.py | 19 +- imap_l3_processing/swapi/l3b/models.py | 48 +- .../calculate_solar_wind_differential_flux.py | 19 +- .../l3b/science/calculate_solar_wind_vdf.py | 102 +- .../geometric_factor_calibration_table.py | 2 +- .../swapi/l3b/swapi_l3b_dependencies.py | 60 +- imap_l3_processing/swapi/quality_flags.py | 2 +- .../swapi/response/azimuthal_transmission.py | 6 +- .../response/efficiency_calibration_table.py | 23 +- .../swapi/response/passband_grid.py | 4 +- .../swapi/response/swapi_response.py | 26 +- imap_l3_processing/swapi/swapi_processor.py | 26 +- imap_l3_processing/swe/l3/models.py | 641 ++-- .../swe/l3/science/moment_calculations.py | 604 ++-- .../swe/l3/science/pitch_calculations.py | 452 ++- .../swe/l3/swe_l3_dependencies.py | 76 +- imap_l3_processing/swe/l3/utils.py | 47 +- imap_l3_processing/swe/quality_flags.py | 24 +- imap_l3_processing/swe/swe_processor.py | 132 +- imap_l3_processing/ultra/models.py | 36 +- .../science/ultra_survival_probability.py | 124 +- .../ultra/ultra_combined_nsp_initializer.py | 87 +- .../ultra/ultra_l3_dependencies.py | 168 +- .../ultra_l3_to_rectangular_dependencies.py | 5 +- imap_l3_processing/ultra/ultra_processor.py | 211 +- .../ultra/ultra_sp_initializer.py | 87 +- imap_l3_processing/utils.py | 198 +- imap_l3_processing/version.py | 2 +- run_local.py | 1363 +++++--- run_local_with_upload_and_download.py | 712 ++-- scripts/batch_download_parents.py | 16 +- scripts/clean_metadata.py | 13 +- .../create_fake_efficiency_ancillary.py | 21 +- .../create_more_accurate_l3a_direct_event.py | 35 +- ...te_more_accurate_l3a_direct_event_input.py | 83 +- scripts/compare_l2_map_metadata.py | 2 - scripts/confirm_reprocessing.py | 20 +- scripts/convert_hit_event_type_to_csv.py | 5 +- scripts/convert_product_definition_to_yaml.py | 110 +- scripts/convert_variable_yaml_to_csv.py | 14 +- scripts/fetch_latest_data.py | 4 +- scripts/generate_hi_yaml.py | 45 +- scripts/generate_lo_yaml.py | 52 +- scripts/generate_repointing_lines.py | 12 +- scripts/generate_ultra_yaml.py | 41 +- scripts/get_batch_jobs_status.py | 61 +- ...le_glows_l3e_survival_probabilities_cdf.py | 36 +- .../glows/create_l2_glows_cdf_from_json.py | 17 +- .../glows/create_l3a_glows_cdf_from_json.py | 27 +- scripts/glows/download_l2_prod_data.py | 17 +- scripts/glows/download_validation_data.py | 26 +- scripts/glows/upload_l3a_ancillary_files.py | 10 +- scripts/hi/create_all_maps_from_inputs.py | 31 +- scripts/hi/create_cdf_from_ibex.py | 22 +- .../create_cdf_from_instrument_team_data.py | 114 +- scripts/hi/create_hi_full_spin_deps.py | 124 +- scripts/hi/create_l2_from_pointing_sets.py | 33 +- scripts/hi/generate_fake_l1c_cdfs.py | 25 +- ...tack_arrays_to_match_number_of_energies.py | 25 +- scripts/hit/create_l1a_direct-event_data.py | 17 +- ...eate_l2_hit_sectored_rates_cdf_from_csv.py | 24 +- scripts/hit/create_mag_from_csv.py | 18 +- scripts/hit/hit_plots.py | 13 +- ...ombine_existing_maps_to_fix_frozen_data.py | 42 +- scripts/lo/create_l2_from_pointing_sets.py | 18 +- scripts/make_cdf_all_fill.py | 7 +- scripts/poll_batch_jobs_status.py | 30 +- scripts/reprocess_all_in_situ.py | 69 +- scripts/run_spectral_index.py | 19 +- ...termine_swapi_files_with_outdated_spice.py | 7 +- ...ha_sw_temperature_density_lut_generator.py | 11 +- scripts/swapi/fake_data_generator.py | 21 +- scripts/swapi/fake_uncertainties_for_cdf.py | 3 +- scripts/swapi/fit_and_plot_alpha.py | 259 +- scripts/swapi/fit_and_plot_proton.py | 263 +- scripts/swapi/fit_and_plot_pui.py | 401 ++- scripts/swapi/generate_cdf_from_dat.py | 23 +- ...erate_collapsed_response_grid_reference.py | 85 +- scripts/swapi/generate_reference_integrals.py | 12 +- .../generate_with_predicted_ephemeris.py | 64 +- scripts/swapi/pui_xarray_reference.py | 167 +- scripts/swapi/pui_xarray_reference_50sweep.py | 55 +- .../report_out_of_range_uncertainties.py | 2 +- ...alpha_sw_speed_temperature_density_demo.py | 125 +- scripts/swapi/upload_swapi_l3_dependencies.py | 15 +- scripts/swapi/view_one_pui_spectrum.py | 303 +- scripts/swe/calculate_rebin_by_pitch_angle.py | 103 +- scripts/swe/compare_outputs.py | 83 +- scripts/swe/create_fake_l2_cdf.py | 239 +- .../swe/filter_good_times_from_l1b_sdc_cdf.py | 76 +- .../swe/filter_good_times_from_l2_sdc_cdf.py | 28 +- ...ci_using_swapi_with_predicted_ephemeris.py | 67 +- scripts/swe/plot_swe.py | 16 +- scripts/swe/read_ace.py | 181 +- scripts/swe/swe_l2.py | 13 +- scripts/swe/swe_l2_old.py | 15 +- scripts/time_shift_cdf.py | 27 +- scripts/truncate_cdf.py | 8 +- .../ultra/create_example_ultra_l1c_pset.py | 101 +- scripts/ultra/create_example_ultra_l2_map.py | 119 +- ...ate_example_ultra_l2_map_with_power_law.py | 51 +- ...ple_ultra_l3_survival_probabilities_cdf.py | 48 +- .../ultra/create_glows_l3e_cdf_from_dat.py | 25 +- ...c_l2_and_glows_with_matching_date_range.py | 52 +- ...create_l2_cdf_from_instrument_team_data.py | 81 +- scripts/ultra/create_l2_dependency_files.py | 66 +- scripts/ultra/create_l2_from_pointing_sets.py | 15 +- scripts/ultra/plot_l2_uncertainties.py | 40 +- .../validation/create_L2_validation_maps.py | 43 +- .../validation/create_l3_validation_maps.py | 30 +- .../prepare_glows_for_ultra_validation.py | 15 +- ...e_ul_repoint_files_for_ultra_validation.py | 14 +- scripts/ultra/validation/upload_files.py | 22 +- tests/cdf/test_cdf_utils.py | 520 ++- tests/cdf/test_imap_attribute_manager.py | 221 +- tests/cdf/test_yaml_var_metadata.py | 5 +- ..._codice_hi_mass_correction_lookup_table.py | 52 +- ...t_codice_l3a_direct_events_dependencies.py | 157 +- .../test_codice_pitch_angle_dependencies.py | 115 +- .../codice/l3/hi/test_codice_hi_processor.py | 578 +++- tests/codice/l3/hi/test_models.py | 394 ++- .../science/test_angle_lookups.py | 61 +- .../science/test_efficiency_lookup.py | 36 +- .../science/test_energy_lookup.py | 29 +- .../science/test_geometric_factor_lookup.py | 309 +- .../science/test_mass_coefficient_lookup.py | 13 +- .../science/test_mass_species_bin_lookup.py | 31 +- .../lo/science/test_codice_lo_calculations.py | 665 ++-- .../test_mass_per_charge_lookup.py | 14 +- ...odice_lo_l3a_direct_events_dependencies.py | 165 +- ...e_lo_l3a_partial_densities_dependencies.py | 127 +- .../test_codice_lo_l3a_ratios_dependencies.py | 30 +- ...ce_lo_l3b_3d_distributions_dependencies.py | 131 +- .../codice/l3/lo/test_codice_lo_processor.py | 1674 ++++++--- tests/codice/l3/lo/test_models.py | 938 +++-- tests/debug_utils/profile_wrappers.py | 2 +- .../test_bad_angle_flag_configuration.py | 45 +- .../test_calculate_daily_lightcurve.py | 228 +- ...ime_independent_background_lookup_table.py | 30 +- .../glows/l3a/test_glows_l3a_dependencies.py | 90 +- tests/glows/l3a/test_models.py | 311 +- tests/glows/l3a/test_utils.py | 436 ++- tests/glows/l3bc/l3bc_toolkit/test_funcs.py | 18 +- .../l3bc/science/test_filter_out_bad_days.py | 14 +- .../glows/l3bc/science/test_generate_l3bc.py | 137 +- tests/glows/l3bc/science/test_time_parsing.py | 66 +- tests/glows/l3bc/test_dependency_validator.py | 100 +- .../l3bc/test_glows_l3bc_dependencies.py | 88 +- .../glows/l3bc/test_glows_l3bc_initializer.py | 608 +++- tests/glows/l3bc/test_models.py | 535 ++- tests/glows/l3bc/test_utils.py | 135 +- .../glows/l3d/test_glows_l3d_dependencies.py | 152 +- tests/glows/l3d/test_glows_l3d_initializer.py | 665 ++-- tests/glows/l3d/test_l3d_utils.py | 517 ++- tests/glows/l3d/test_models.py | 77 +- .../l3e/test_glows_l3e_call_arguments.py | 10 +- .../glows/l3e/test_glows_l3e_dependencies.py | 317 +- tests/glows/l3e/test_glows_l3e_hi_model.py | 1013 +++++- tests/glows/l3e/test_glows_l3e_initializer.py | 301 +- tests/glows/l3e/test_glows_l3e_lo_model.py | 723 +++- tests/glows/l3e/test_glows_l3e_ultra_model.py | 378 ++- tests/glows/l3e/test_glows_l3e_utils.py | 924 +++-- tests/glows/l3e/test_reprocess_info.py | 136 +- tests/glows/test_glows_processor.py | 2681 ++++++++++----- tests/hi/test_hi_combined_dependencies.py | 71 +- tests/hi/test_hi_combined_initializer.py | 469 +-- tests/hi/test_hi_processor.py | 664 ++-- tests/hi/test_hi_sp_initializer.py | 727 ++-- tests/hi/test_hi_spectral_fit_dependencies.py | 55 +- tests/hi/test_utils.py | 134 +- tests/hit/l3/hit_test_builders.py | 58 +- .../hit/l3/pha/science/test_calculate_pha.py | 740 ++-- .../test_cosine_correction_lookup_table.py | 111 +- .../l3/pha/science/test_gain_lookup_table.py | 12 +- .../pha/science/test_hit_event_type_lookup.py | 54 +- .../l3/pha/science/test_range_fit_lookup.py | 76 +- tests/hit/l3/pha/test_l3_pha_dependencies.py | 220 +- tests/hit/l3/pha/test_pha_event_reader.py | 318 +- .../test_sectored_products_algorithms.py | 23 +- tests/hit/l3/sectored_products/test_models.py | 389 ++- tests/hit/l3/test_hit_processor.py | 1188 +++++-- tests/hit/l3/test_l3_sectored_dependencies.py | 108 +- tests/hit/l3/test_models.py | 173 +- tests/hit/l3/test_utils.py | 197 +- tests/integration/integration_test_helpers.py | 67 +- .../test_codice_processor_integration.py | 65 +- .../test_glows_processor_integration.py | 643 ++-- .../test_hit_processor_integration.py | 28 +- .../test_map_processor_integration.py | 434 ++- .../test_swapi_processor_integration.py | 240 +- .../test_swe_processor_integration.py | 15 +- tests/lo/l3/test_lo_combined_dependencies.py | 34 +- ..._isn_background_subtracted_dependencies.py | 24 +- .../test_lo_l3_spectral_fit_dependencies.py | 44 +- tests/lo/l3/test_lo_sp_initializer.py | 178 +- tests/lo/test_lo_processor.py | 406 ++- tests/maps/test_builders.py | 178 +- .../test_hilo_l3_survival_dependencies.py | 189 +- tests/maps/test_map_combination.py | 460 ++- tests/maps/test_map_descriptors.py | 539 ++- tests/maps/test_map_models.py | 598 +++- .../test_rectangular_survival_probability.py | 944 ++++-- tests/maps/test_spectral_fit.py | 825 +++-- .../test_survival_probability_processing.py | 528 ++- ...test_convert_product_definition_to_yaml.py | 173 +- tests/swapi/_helpers.py | 5 +- tests/swapi/cdf_model_test_case.py | 32 +- .../test_build_collapsed_response_grid.py | 13 +- .../test_calculate_coincidence_rate.py | 17 +- ..._density_of_neutral_helium_lookup_table.py | 5 +- .../pickup_ion/test_goodness_of_fit.py | 78 +- .../l3a/science/pickup_ion/test_utils.py | 31 +- .../test_vasyliunas_siscoe_distribution.py | 14 +- .../alpha/test_fit_solar_wind_alpha_model.py | 105 +- .../proton/test_calculate_initial_guess.py | 44 +- .../proton/test_escape_local_minimum.py | 114 +- .../test_fit_solar_wind_proton_model.py | 149 +- .../test_optimize_solar_wind_proton_params.py | 12 +- .../solar_wind/test_azimuthal_regions.py | 3 +- .../science/solar_wind/test_fit_context.py | 20 +- .../science/solar_wind/test_forward_model.py | 11 +- .../solar_wind/test_integration_limits.py | 35 +- .../l3a/science/solar_wind/test_params.py | 4 +- .../solar_wind/test_trim_open_aperture.py | 34 +- .../test_uncertainty_calibration.py | 22 +- .../l3a/science/solar_wind/test_utils.py | 8 +- tests/swapi/l3a/science/test_inflow_vector.py | 16 +- tests/swapi/l3a/test_chunk_fits.py | 34 +- tests/swapi/l3a/test_models.py | 457 ++- .../swapi/l3a/test_swapi_l3a_dependencies.py | 240 +- tests/swapi/l3a/test_utils.py | 185 +- ..._calculate_solar_wind_differential_flux.py | 22 +- .../science/test_calculate_solar_wind_vdf.py | 45 +- ...test_geometric_factor_calibration_table.py | 18 +- tests/swapi/l3b/test_models.py | 86 +- .../swapi/l3b/test_swapi_l3b_dependencies.py | 140 +- .../response/test_azimuthal_transmission.py | 24 +- .../test_efficiency_calibration_table.py | 134 +- tests/swapi/response/test_passband_grid.py | 23 +- tests/swapi/response/test_swapi_response.py | 93 +- tests/swapi/test_swapi_processor.py | 970 ++++-- tests/swe/l3/science/test_models.py | 713 +++- .../l3/science/test_moments_calculation.py | 1795 +++++++--- .../swe/l3/science/test_pitch_calculations.py | 778 +++-- tests/swe/l3/test_swe_l3_dependencies.py | 115 +- tests/swe/l3/test_utils.py | 71 +- tests/swe/test_swe_processor.py | 3019 ++++++++++++----- .../3S5_l1b_ram_maps/archive/map_SCFrame.py | 219 +- .../3S5_l1b_ram_maps/crap/new_patch_arc2.py | 425 ++- .../3S5_l1b_ram_maps/csv2yaml.py | 171 +- .../3S5_l1b_ram_maps/csv_to_soc.py | 85 +- .../3S5_l1b_ram_maps/l1b_to_spin.py | 316 +- .../3S5_l1b_ram_maps/map_SCFrame.py | 314 +- .../3S5_l1b_ram_maps/new_patch_arc2.py | 442 ++- .../3S5_l1b_ram_maps/new_patch_arc2_linear.py | 432 ++- .../3S5_l1b_ram_maps/old/csv2yaml.py | 132 +- .../3S5_l1b_ram_maps/plot_map_DN.py | 213 +- tests/test_data_utils.py | 366 +- tests/test_helpers.py | 168 +- tests/test_imap_l3_data_processor.py | 763 +++-- tests/test_models.py | 94 +- tests/test_pitch_angles.py | 395 ++- tests/test_predicted_ephemeris_tracker.py | 10 +- tests/test_processor.py | 22 +- tests/test_utils.py | 678 ++-- tests/ultra/test_models.py | 75 +- .../test_ultra_combined_nsp_initializer.py | 276 +- tests/ultra/test_ultra_l3_dependencies.py | 866 +++-- .../test_ultra_l3_survival_probabillity.py | 515 ++- ...st_ultra_l3_to_rectangular_dependencies.py | 38 +- tests/ultra/test_ultra_processor.py | 993 ++++-- tests/ultra/test_ultra_sp_initializer.py | 753 ++-- 428 files changed, 51390 insertions(+), 25019 deletions(-) diff --git a/docs/swapi/figure_src/figure_utils.py b/docs/swapi/figure_src/figure_utils.py index 9e9dc7b2..84623c6c 100644 --- a/docs/swapi/figure_src/figure_utils.py +++ b/docs/swapi/figure_src/figure_utils.py @@ -4,8 +4,9 @@ import os import sys import time +from collections.abc import Callable from pathlib import Path -from typing import Callable, TypeVar +from typing import TypeVar import numpy as np @@ -42,14 +43,68 @@ def load_swapi_response() -> SwapiResponse: COARSE_SWEEP_VOLTAGES_MEAN_V = np.array( [ - 9895.52, 9088.69, 8348.80, 7667.55, 7042.16, 6469.31, 5941.77, 5457.31, - 5013.22, 4603.65, 4230.77, 3886.92, 3569.16, 3278.72, 3011.13, 2766.25, - 2539.54, 2333.83, 2144.24, 1969.31, 1808.74, 1660.86, 1525.75, 1401.82, - 1287.58, 1182.24, 1085.15, 995.55, 914.31, 839.94, 771.70, 709.46, - 651.59, 598.47, 549.91, 505.12, 463.89, 425.92, 391.18, 359.35, - 329.94, 303.02, 278.25, 255.55, 234.77, 215.61, 197.95, 181.82, - 167.04, 153.46, 140.91, 129.50, 118.91, 109.20, 100.30, 92.11, - 84.61, 77.73, 71.40, 65.59, 60.23, 55.34, + 9895.52, + 9088.69, + 8348.80, + 7667.55, + 7042.16, + 6469.31, + 5941.77, + 5457.31, + 5013.22, + 4603.65, + 4230.77, + 3886.92, + 3569.16, + 3278.72, + 3011.13, + 2766.25, + 2539.54, + 2333.83, + 2144.24, + 1969.31, + 1808.74, + 1660.86, + 1525.75, + 1401.82, + 1287.58, + 1182.24, + 1085.15, + 995.55, + 914.31, + 839.94, + 771.70, + 709.46, + 651.59, + 598.47, + 549.91, + 505.12, + 463.89, + 425.92, + 391.18, + 359.35, + 329.94, + 303.02, + 278.25, + 255.55, + 234.77, + 215.61, + 197.95, + 181.82, + 167.04, + 153.46, + 140.91, + 129.50, + 118.91, + 109.20, + 100.30, + 92.11, + 84.61, + 77.73, + 71.40, + 65.59, + 60.23, + 55.34, ] ) diff --git a/docs/swapi/figure_src/plot_alpha_peak_finding.py b/docs/swapi/figure_src/plot_alpha_peak_finding.py index 0b8446d5..6cf26ef1 100644 --- a/docs/swapi/figure_src/plot_alpha_peak_finding.py +++ b/docs/swapi/figure_src/plot_alpha_peak_finding.py @@ -34,6 +34,8 @@ sys.path.insert(0, str(Path(__file__).resolve().parents[3])) +from figure_utils import FIGURES_DIR, load_swapi_response + from imap_l3_processing.constants import ( ALPHA_MASS_PER_CHARGE_M_P_PER_E, ALPHA_PARTICLE_MASS_KG, @@ -70,7 +72,6 @@ ) from imap_l3_processing.swapi.response.deadtime import deadtime_factor from imap_l3_processing.utils import SpiceKernelTypes -from figure_utils import FIGURES_DIR, load_swapi_response DATE_YYYYMMDD = "20260101" N_SWEEPS = 5 @@ -187,8 +188,12 @@ def _read_5_sweep_block( def _coarse_measurement_times_ns(epoch_ns: np.ndarray) -> np.ndarray: coarse_bins = np.arange(SWAPI_COARSE_SWEEP_BINS.start, SWAPI_COARSE_SWEEP_BINS.stop) - seconds_into_sweep = coarse_bins * SWAPI_BIN_PERIOD_S + SWAPI_LIVETIME_CENTER_OFFSET_S - return (epoch_ns[:, None] + seconds_into_sweep * ONE_SECOND_IN_NANOSECONDS).flatten() + seconds_into_sweep = ( + coarse_bins * SWAPI_BIN_PERIOD_S + SWAPI_LIVETIME_CENTER_OFFSET_S + ) + return ( + epoch_ns[:, None] + seconds_into_sweep * ONE_SECOND_IN_NANOSECONDS + ).flatten() # --------------------------------------------------------------------------- # @@ -261,9 +266,7 @@ def _plot_case(ax, swapi_response, cdf_path, mag_data, chunk_index): proton_moments=proton_moments, magnetic_field_direction=b_hat, ) - alpha_velocity_rtn = np.array( - [c.nominal_value for c in alpha_moments.velocity_rtn] - ) + alpha_velocity_rtn = np.array([c.nominal_value for c in alpha_moments.velocity_rtn]) alpha_sw = SolarWindParams( density=alpha_moments.density.nominal_value, velocity_rtn=alpha_velocity_rtn, diff --git a/docs/swapi/figure_src/plot_calibration_curves.py b/docs/swapi/figure_src/plot_calibration_curves.py index ba062887..e96022be 100644 --- a/docs/swapi/figure_src/plot_calibration_curves.py +++ b/docs/swapi/figure_src/plot_calibration_curves.py @@ -17,9 +17,9 @@ import matplotlib.pyplot as plt import numpy as np import pandas as pd +from figure_utils import FIGURES_DIR, load_swapi_response from imap_l3_processing.swapi.response.swapi_response import SwapiResponse -from figure_utils import FIGURES_DIR, load_swapi_response _AREA_CSV = ( Path(__file__).resolve().parents[3] diff --git a/docs/swapi/figure_src/plot_collapsed_response_grid.py b/docs/swapi/figure_src/plot_collapsed_response_grid.py index 53be77b2..7211d9a5 100644 --- a/docs/swapi/figure_src/plot_collapsed_response_grid.py +++ b/docs/swapi/figure_src/plot_collapsed_response_grid.py @@ -23,16 +23,20 @@ import matplotlib.pyplot as plt import numpy as np import pandas as pd +from figure_utils import FIGURES_DIR, REPO_ROOT, load_swapi_response +from imap_l3_processing.constants import HE_PUI_PARTICLE_MASS_PER_CHARGE_M_P_PER_E from imap_l3_processing.swapi.l3a.science.pickup_ion.collapsed_response_grid import ( build_collapsed_response_grid, solar_wind_frame_speed_range, ) -from figure_utils import FIGURES_DIR, REPO_ROOT, load_swapi_response -from imap_l3_processing.constants import HE_PUI_PARTICLE_MASS_PER_CHARGE_M_P_PER_E _REFERENCE_CSV_PATH = ( - REPO_ROOT / "tests" / "test_data" / "swapi" / "collapsed_response_grid_reference.csv" + REPO_ROOT + / "tests" + / "test_data" + / "swapi" + / "collapsed_response_grid_reference.csv" ) _ESA_VOLTAGE = 5000.0 diff --git a/docs/swapi/figure_src/plot_fit_accuracy.py b/docs/swapi/figure_src/plot_fit_accuracy.py index 795583de..5ec33786 100644 --- a/docs/swapi/figure_src/plot_fit_accuracy.py +++ b/docs/swapi/figure_src/plot_fit_accuracy.py @@ -29,19 +29,13 @@ import types +import matplotlib import numpy as np import pandas as pd from uncertainties import UFloat -import matplotlib matplotlib.use("Agg") import matplotlib.pyplot as plt - -from imap_l3_processing.constants import ( - PROTON_MASS_KG, - PROTON_MASS_PER_CHARGE_M_P_PER_E, -) -from imap_l3_processing.swapi.constants import SWAPI_LIVETIME_S from figure_utils import ( COARSE_BIN_INDICES_IN_SWEEP, COARSE_SWEEP_VOLTAGES_MEAN_V, @@ -50,20 +44,26 @@ load_swapi_response, run_parallel_map, ) -from imap_l3_processing.swapi.l3a.science.solar_wind.proton.fit_solar_wind_proton_model import ( - fit_solar_wind_proton_model, + +from imap_l3_processing.constants import ( + PROTON_MASS_KG, + PROTON_MASS_PER_CHARGE_M_P_PER_E, ) -from imap_l3_processing.swapi.l3a.science.solar_wind.proton.calculate_initial_guess import ( - calculate_initial_guess, +from imap_l3_processing.swapi.constants import SWAPI_LIVETIME_S +from imap_l3_processing.swapi.l3a.science.solar_wind.fit_context import ( + build_solar_wind_fit_context, ) from imap_l3_processing.swapi.l3a.science.solar_wind.forward_model import ( model_solar_wind_ideal_coincidence_rates, ) -from imap_l3_processing.swapi.response.deadtime import deadtime_factor -from imap_l3_processing.swapi.l3a.science.solar_wind.fit_context import ( - build_solar_wind_fit_context, -) from imap_l3_processing.swapi.l3a.science.solar_wind.params import SolarWindParams +from imap_l3_processing.swapi.l3a.science.solar_wind.proton.calculate_initial_guess import ( + calculate_initial_guess, +) +from imap_l3_processing.swapi.l3a.science.solar_wind.proton.fit_solar_wind_proton_model import ( + fit_solar_wind_proton_model, +) +from imap_l3_processing.swapi.response.deadtime import deadtime_factor _N_SWEEPS = 5 _N_BINS = len(COARSE_SWEEP_VOLTAGES_MEAN_V) @@ -188,10 +188,11 @@ def _process_one(i): result = fit_solar_wind_proton_model(fit_ctx) except Exception as e: print(f" case {i}: fit failed ({type(e).__name__}: {e}); flagging bad") + from uncertainties import ufloat + from imap_l3_processing.swapi.l3a.science.solar_wind.proton.fit_solar_wind_proton_model import ( ProtonSolarWindFitResult, ) - from uncertainties import ufloat nan_uf = ufloat(float("nan"), float("nan")) result = ProtonSolarWindFitResult( @@ -315,7 +316,7 @@ def _plot_results(data: pd.DataFrame) -> None: marker="o", zorder=2, label="Initial guess", - rasterized=True + rasterized=True, ) ax.errorbar( truth[good], @@ -344,7 +345,7 @@ def _plot_results(data: pd.DataFrame) -> None: edgecolors="k", linewidths=0.4, zorder=4, - rasterized=True + rasterized=True, ) ax.scatter( truth[~good], @@ -356,7 +357,7 @@ def _plot_results(data: pd.DataFrame) -> None: edgecolors="k", linewidths=0.4, zorder=4, - rasterized=True + rasterized=True, ) ax.set_xlabel(f"True {label}", fontsize=9) diff --git a/docs/swapi/figure_src/plot_passband_boundaries.py b/docs/swapi/figure_src/plot_passband_boundaries.py index 862d543e..5187f9b2 100644 --- a/docs/swapi/figure_src/plot_passband_boundaries.py +++ b/docs/swapi/figure_src/plot_passband_boundaries.py @@ -8,10 +8,10 @@ matplotlib.use("Agg") import matplotlib.pyplot as plt import numpy as np +from figure_utils import FIGURES_DIR, load_swapi_response from imap_l3_processing.swapi.response.passband_grid import PassbandGrid from imap_l3_processing.swapi.response.swapi_response import SwapiResponse -from figure_utils import FIGURES_DIR, load_swapi_response _ELEVATION_DISPLAY_LIMIT_DEG = 15.0 _ACTIVE_ELEVATION_SAMPLE_COUNT = 300 @@ -85,9 +85,7 @@ def plot_region_panel( grid, grid.max_boundary, active_elevations, np.maximum ) - image = draw_transmission_heatmap( - axis, grid.values, elevations, speed_ratios - ) + image = draw_transmission_heatmap(axis, grid.values, elevations, speed_ratios) draw_integration_window_outline( axis, active_elevations, lower_speed_ratios, upper_speed_ratios ) diff --git a/docs/swapi/figure_src/plot_pui_cutoff_staircase.py b/docs/swapi/figure_src/plot_pui_cutoff_staircase.py index 9d16ad2a..a075e092 100644 --- a/docs/swapi/figure_src/plot_pui_cutoff_staircase.py +++ b/docs/swapi/figure_src/plot_pui_cutoff_staircase.py @@ -34,10 +34,12 @@ import matplotlib.pyplot as plt import numpy as np import pandas as pd - from figure_utils import FIGURES_DIR, load_swapi_response -from imap_l3_processing.constants import HE_PUI_PARTICLE_MASS_PER_CHARGE_M_P_PER_E, ONE_AU_IN_KM +from imap_l3_processing.constants import ( + HE_PUI_PARTICLE_MASS_PER_CHARGE_M_P_PER_E, + ONE_AU_IN_KM, +) from imap_l3_processing.swapi.l3a.science.pickup_ion.calculate_coincidence_rate import ( apply_partial_heaviside_at_cutoff, calculate_coincidence_rate, @@ -53,7 +55,9 @@ FittingParameters, VasyliunasSiscoeDistribution, ) -from imap_l3_processing.swapi.l3a.utils import velocity_components_to_angles_in_instrument_frame +from imap_l3_processing.swapi.l3a.utils import ( + velocity_components_to_angles_in_instrument_frame, +) _SW_SPEED_KMS = 450.0 _SW_AZIMUTH_DEG = 0.0 @@ -90,9 +94,13 @@ def _params(cutoff_speed_kms: float) -> FittingParameters: def main(): - voltages = pd.read_csv( - REPO_ROOT / "tests" / "test_data" / "swapi" / "pui_count_rate_reference.csv" - ).iloc[:, 0].to_numpy() + voltages = ( + pd.read_csv( + REPO_ROOT / "tests" / "test_data" / "swapi" / "pui_count_rate_reference.csv" + ) + .iloc[:, 0] + .to_numpy() + ) voltage_index = int(np.argmin(np.abs(voltages - _ESA_VOLTAGE_V))) swapi_response = load_swapi_response() @@ -109,11 +117,13 @@ def main(): azimuth_rad = np.radians(_SW_AZIMUTH_DEG) elevation_rad = np.radians(_SW_ELEVATION_DEG) - bulk_vec = _SW_SPEED_KMS * np.array([ - -np.cos(elevation_rad) * np.sin(azimuth_rad), - -np.cos(elevation_rad) * np.cos(azimuth_rad), - -np.sin(elevation_rad), - ]) + bulk_vec = _SW_SPEED_KMS * np.array( + [ + -np.cos(elevation_rad) * np.sin(azimuth_rad), + -np.cos(elevation_rad) * np.cos(azimuth_rad), + -np.sin(elevation_rad), + ] + ) bulk_per_bin = np.broadcast_to(bulk_vec, (1, voltages.size, 3)).copy() chunk_response = build_chunk_collapsed_response( @@ -130,8 +140,10 @@ def main(): bin_weights = chunk_response.bin_weights[0, voltage_index, :] # Fine-grid reference response for the same voltage step. - bulk_azimuth_deg, bulk_elevation_deg = velocity_components_to_angles_in_instrument_frame( - bulk_vec[0], bulk_vec[1], bulk_vec[2] + bulk_azimuth_deg, bulk_elevation_deg = ( + velocity_components_to_angles_in_instrument_frame( + bulk_vec[0], bulk_vec[1], bulk_vec[2] + ) ) fine_grid = np.linspace(1.0, _GRID_MAX_KMS, _FINE_GRID_POINTS) fine_collapsed = build_collapsed_response_grid( @@ -145,9 +157,7 @@ def main(): bulk_elevation_deg, speed_in_sw_frame=fine_grid, ) - fine_weights = ( - fine_collapsed.values * fine_grid**2 * (fine_grid[1] - fine_grid[0]) - ) + fine_weights = fine_collapsed.values * fine_grid**2 * (fine_grid[1] - fine_grid[0]) # Below the neutral-helium LUT support the distribution is physically zero; # the LUT extrapolation returns non-finite values there, so clamp them. @@ -190,15 +200,26 @@ def sampled_distribution(grid, params, apply_cutoff): axis.axvline(grid_edges[0], color="0.85", lw=0.8, zorder=0, label="$v'$ grid edges") axis.plot( - _CUTOFF_SWEEP_KMS, rate_reference, "-", color="0.4", lw=1, - label=f"fine-grid reference", + _CUTOFF_SWEEP_KMS, + rate_reference, + "-", + color="0.4", + lw=1, + label="fine-grid reference", ) axis.scatter( - _CUTOFF_SWEEP_KMS, rate_without, color="tab:red", s=10, + _CUTOFF_SWEEP_KMS, + rate_without, + color="tab:red", + s=10, label="no correction", ) axis.scatter( - _CUTOFF_SWEEP_KMS, rate_with, color="tab:blue", s=10, marker='x', + _CUTOFF_SWEEP_KMS, + rate_with, + color="tab:blue", + s=10, + marker="x", label="with correction", ) @@ -207,7 +228,10 @@ def sampled_distribution(grid, params, apply_cutoff): axis.set_xlim(_CUTOFF_SWEEP_KMS[0], _CUTOFF_SWEEP_KMS[-1]) axis.annotate( rf"grid $\Delta v' = {delta_v_prime:.2f}$ km/s", - xy=(0.02, 0.04), xycoords="axes fraction", fontsize=9, color="0.3", + xy=(0.02, 0.04), + xycoords="axes fraction", + fontsize=9, + color="0.3", ) axis.grid(True, alpha=0.3) axis.legend(loc="upper left") diff --git a/docs/swapi/figure_src/plot_pui_distribution.py b/docs/swapi/figure_src/plot_pui_distribution.py index 79275342..f8fc254c 100644 --- a/docs/swapi/figure_src/plot_pui_distribution.py +++ b/docs/swapi/figure_src/plot_pui_distribution.py @@ -27,7 +27,6 @@ matplotlib.use("Agg") import matplotlib.pyplot as plt import numpy as np - from figure_utils import FIGURES_DIR from imap_l3_processing.constants import ONE_AU_IN_KM @@ -92,7 +91,9 @@ def main(): label=r"cutoff speed $v_b$", ) axis.set_yscale("log") - axis.set_xlabel(r"Comoving speed $v' = \|\mathbf{v} - \mathbf{v}_\text{sw}\|$ [km/s]") + axis.set_xlabel( + r"Comoving speed $v' = \|\mathbf{v} - \mathbf{v}_\text{sw}\|$ [km/s]" + ) axis.set_ylabel(r"$f_\text{PUI}(v')$ [s$^3$ km$^{-6}$]") axis.set_xlim(speed_in_sw_frame[0], speed_in_sw_frame[-1]) axis.set_ylim(1e0, 1e4) diff --git a/docs/swapi/figure_src/plot_pui_reference_comparison.py b/docs/swapi/figure_src/plot_pui_reference_comparison.py index 9b32aaab..e39a32b2 100644 --- a/docs/swapi/figure_src/plot_pui_reference_comparison.py +++ b/docs/swapi/figure_src/plot_pui_reference_comparison.py @@ -27,8 +27,8 @@ import matplotlib.pyplot as plt import numpy as np import pandas as pd - from figure_utils import FIGURES_DIR + from imap_l3_processing.constants import HE_PUI_PARTICLE_MASS_PER_CHARGE_M_P_PER_E _REFERENCE_CSV_PATH = ( @@ -59,6 +59,8 @@ def compute_production_rates(voltages_v: np.ndarray) -> np.ndarray: """Build the chunk-level collapsed response and call the in-development production kernel. Imports live inside the function so a broken module doesn't break the figure script at import time.""" + from figure_utils import load_swapi_response + from imap_l3_processing.constants import ONE_AU_IN_KM from imap_l3_processing.swapi.l3a.science.pickup_ion.calculate_coincidence_rate import ( calculate_coincidence_rate, @@ -73,7 +75,6 @@ def compute_production_rates(voltages_v: np.ndarray) -> np.ndarray: FittingParameters, VasyliunasSiscoeDistribution, ) - from figure_utils import load_swapi_response fitting_params = FittingParameters( cooling_index=_COOLING_INDEX, @@ -95,14 +96,14 @@ def compute_production_rates(voltages_v: np.ndarray) -> np.ndarray: sw_az_rad = np.radians(_SW_AZIMUTH_DEG) sw_el_rad = np.radians(_SW_ELEVATION_DEG) - bulk_vec = _SW_SPEED_KMS * np.array([ - -np.cos(sw_el_rad) * np.sin(sw_az_rad), - -np.cos(sw_el_rad) * np.cos(sw_az_rad), - -np.sin(sw_el_rad), - ]) - bulk_sw_per_bin = np.broadcast_to( - bulk_vec, (1, voltages_v.size, 3) - ).copy() + bulk_vec = _SW_SPEED_KMS * np.array( + [ + -np.cos(sw_el_rad) * np.sin(sw_az_rad), + -np.cos(sw_el_rad) * np.cos(sw_az_rad), + -np.sin(sw_el_rad), + ] + ) + bulk_sw_per_bin = np.broadcast_to(bulk_vec, (1, voltages_v.size, 3)).copy() swapi_response = load_swapi_response() swapi_response.warm_cache(voltages_v) @@ -115,7 +116,9 @@ def compute_production_rates(voltages_v: np.ndarray) -> np.ndarray: min_speed_kms=min_speed_kms, central_effective_area_scale=_HELIUM_EFFICIENCY_RATIO, ) - return calculate_coincidence_rate(chunk_response, vasyliunas_siscoe_distribution, fitting_params)[0] + return calculate_coincidence_rate( + chunk_response, vasyliunas_siscoe_distribution, fitting_params + )[0] def main(): @@ -133,11 +136,17 @@ def main(): ) sw_az_rad = np.radians(_SW_AZIMUTH_DEG) sw_el_rad = np.radians(_SW_ELEVATION_DEG) - bulk_vec = _SW_SPEED_KMS * np.array([ - -np.cos(sw_el_rad) * np.sin(sw_az_rad), - -np.cos(sw_el_rad) * np.cos(sw_az_rad), - -np.sin(sw_el_rad), - ]) + 0.0 # normalize -0.0 to +0.0 for display + bulk_vec = ( + _SW_SPEED_KMS + * np.array( + [ + -np.cos(sw_el_rad) * np.sin(sw_az_rad), + -np.cos(sw_el_rad) * np.cos(sw_az_rad), + -np.sin(sw_el_rad), + ] + ) + + 0.0 + ) # normalize -0.0 to +0.0 for display axes[0].set_title( f"PUI He coincidence rate — m/q={_HELIUM_MASS_PER_CHARGE_M_P_PER_E:.0f}, " f"efficiency ratio={_HELIUM_EFFICIENCY_RATIO:.2f}\n" @@ -165,7 +174,7 @@ def main(): ".", color="red", label="Optimized", - markersize=4 + markersize=4, ) rel_err = np.abs(production_rate_hz - count_rate_hz) / count_rate_hz axes[1].semilogy(voltage_v, rel_err, ".", color="red") diff --git a/docs/swapi/figure_src/plot_real_data_fit.py b/docs/swapi/figure_src/plot_real_data_fit.py index 70c11f71..7024ce7e 100644 --- a/docs/swapi/figure_src/plot_real_data_fit.py +++ b/docs/swapi/figure_src/plot_real_data_fit.py @@ -37,40 +37,40 @@ sys.path.insert(0, str(Path(__file__).resolve().parents[3])) +import scipy.optimize +from figure_utils import FIGURES_DIR, REPO_ROOT, load_swapi_response + from imap_l3_processing.constants import ( BOLTZMANN_CONSTANT_JOULES_PER_KELVIN, ONE_SECOND_IN_NANOSECONDS, PROTON_MASS_KG, PROTON_MASS_PER_CHARGE_M_P_PER_E, ) -import scipy.optimize - +from imap_l3_processing.swapi.constants import ( + SWAPI_BIN_PERIOD_S, + SWAPI_COARSE_SWEEP_BINS, + SWAPI_FINE_SWEEP_BINS, + SWAPI_K_FACTOR, + SWAPI_L2_K_FACTOR, + SWAPI_LIVETIME_CENTER_OFFSET_S, + SWAPI_SCIENCE_BINS, +) from imap_l3_processing.swapi.l3a.science.solar_wind.fit_context import ( build_solar_wind_fit_context, ) from imap_l3_processing.swapi.l3a.science.solar_wind.forward_model import ( model_solar_wind_ideal_coincidence_rates, ) +from imap_l3_processing.swapi.l3a.science.solar_wind.params import SolarWindParams from imap_l3_processing.swapi.l3a.science.solar_wind.proton.fit_solar_wind_proton_model import ( fit_solar_wind_proton_model, ) -from imap_l3_processing.swapi.l3a.science.solar_wind.params import SolarWindParams from imap_l3_processing.swapi.l3a.utils import ( get_spacecraft_velocity_rtn, get_swapi_geometry, ) from imap_l3_processing.swapi.response.deadtime import deadtime_factor -from imap_l3_processing.swapi.constants import ( - SWAPI_BIN_PERIOD_S, - SWAPI_COARSE_SWEEP_BINS, - SWAPI_FINE_SWEEP_BINS, - SWAPI_K_FACTOR, - SWAPI_L2_K_FACTOR, - SWAPI_LIVETIME_CENTER_OFFSET_S, - SWAPI_SCIENCE_BINS, -) from imap_l3_processing.utils import SpiceKernelTypes -from figure_utils import FIGURES_DIR, REPO_ROOT, load_swapi_response _DOC_PATH = REPO_ROOT / "docs" / "swapi" / "proton-sw.md" _TABLE_BEGIN = "