gammasimtools 0.6.1__py3-none-any.whl → 0.8.1__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.
- gammasimtools-0.8.1.dist-info/METADATA +172 -0
- gammasimtools-0.8.1.dist-info/RECORD +346 -0
- {gammasimtools-0.6.1.dist-info → gammasimtools-0.8.1.dist-info}/WHEEL +1 -1
- gammasimtools-0.8.1.dist-info/entry_points.txt +31 -0
- simtools/_version.py +2 -2
- simtools/applications/calculate_trigger_rate.py +210 -0
- simtools/applications/convert_all_model_parameters_from_simtel.py +372 -0
- simtools/applications/{print_array_elements.py → convert_geo_coordinates_of_array_elements.py} +58 -63
- simtools/applications/convert_model_parameter_from_simtel.py +119 -0
- simtools/applications/{add_file_to_db.py → db_add_file_to_db.py} +70 -60
- simtools/applications/db_add_model_parameters_from_repository_to_db.py +184 -0
- simtools/applications/db_add_value_from_json_to_db.py +105 -0
- simtools/applications/db_development_tools/write_array_elements_positions_to_repository.py +180 -0
- simtools/applications/db_get_array_layouts_from_db.py +162 -0
- simtools/applications/{get_file_from_db.py → db_get_file_from_db.py} +30 -34
- simtools/applications/db_get_parameter_from_db.py +131 -0
- simtools/applications/db_inspect_databases.py +52 -0
- simtools/applications/derive_mirror_rnda.py +39 -255
- simtools/applications/derive_psf_parameters.py +441 -0
- simtools/applications/generate_array_config.py +82 -0
- simtools/applications/generate_corsika_histograms.py +52 -52
- simtools/applications/generate_default_metadata.py +5 -8
- simtools/applications/generate_regular_arrays.py +117 -0
- simtools/applications/generate_simtel_array_histograms.py +97 -56
- simtools/applications/plot_array_layout.py +345 -115
- simtools/applications/production_generate_simulation_config.py +158 -0
- simtools/applications/production_scale_events.py +168 -0
- simtools/applications/simulate_light_emission.py +478 -0
- simtools/applications/simulate_prod.py +97 -175
- simtools/applications/submit_data_from_external.py +9 -12
- simtools/applications/submit_model_parameter_from_external.py +122 -0
- simtools/applications/validate_camera_efficiency.py +35 -102
- simtools/applications/validate_camera_fov.py +20 -19
- simtools/applications/{compare_cumulative_psf.py → validate_cumulative_psf.py} +45 -44
- simtools/applications/validate_file_using_schema.py +113 -47
- simtools/applications/validate_optics.py +17 -22
- simtools/camera_efficiency.py +193 -202
- simtools/configuration/commandline_parser.py +384 -96
- simtools/configuration/configurator.py +55 -71
- simtools/constants.py +5 -5
- simtools/corsika/corsika_config.py +482 -342
- simtools/corsika/corsika_histograms.py +226 -204
- simtools/corsika/corsika_histograms_visualize.py +23 -24
- simtools/corsika/primary_particle.py +159 -0
- simtools/data_model/data_reader.py +25 -20
- simtools/data_model/format_checkers.py +52 -0
- simtools/data_model/metadata_collector.py +210 -184
- simtools/data_model/metadata_model.py +115 -37
- simtools/data_model/model_data_writer.py +335 -26
- simtools/data_model/validate_data.py +366 -154
- simtools/db/db_array_elements.py +130 -0
- simtools/db/db_from_repo_handler.py +106 -0
- simtools/db/db_handler.py +1246 -0
- simtools/io_operations/hdf5_handler.py +3 -1
- simtools/io_operations/io_handler.py +32 -57
- simtools/job_execution/job_manager.py +82 -69
- simtools/layout/array_layout.py +325 -537
- simtools/layout/geo_coordinates.py +8 -11
- simtools/layout/telescope_position.py +163 -86
- simtools/model/array_model.py +305 -256
- simtools/model/calibration_model.py +50 -0
- simtools/model/camera.py +233 -493
- simtools/model/mirrors.py +61 -44
- simtools/model/model_parameter.py +602 -0
- simtools/model/model_utils.py +7 -35
- simtools/model/site_model.py +161 -0
- simtools/model/telescope_model.py +127 -621
- simtools/production_configuration/calculate_statistical_errors_grid_point.py +454 -0
- simtools/production_configuration/event_scaler.py +146 -0
- simtools/production_configuration/generate_simulation_config.py +193 -0
- simtools/production_configuration/interpolation_handler.py +197 -0
- simtools/ray_tracing/__init__.py +0 -0
- simtools/ray_tracing/mirror_panel_psf.py +280 -0
- simtools/{psf_analysis.py → ray_tracing/psf_analysis.py} +133 -47
- simtools/ray_tracing/ray_tracing.py +646 -0
- simtools/runners/__init__.py +0 -0
- simtools/runners/corsika_runner.py +240 -0
- simtools/runners/corsika_simtel_runner.py +225 -0
- simtools/runners/runner_services.py +307 -0
- simtools/runners/simtel_runner.py +224 -0
- simtools/schemas/array_elements.yml +137 -0
- simtools/schemas/integration_tests_config.metaschema.yml +93 -0
- simtools/schemas/metadata.metaschema.yml +6 -0
- simtools/schemas/model_parameter.metaschema.yml +78 -0
- simtools/schemas/{data.metaschema.yml → model_parameter_and_data_schema.metaschema.yml} +27 -44
- simtools/schemas/model_parameters/adjust_gain.schema.yml +37 -0
- simtools/schemas/model_parameters/altitude.schema.yml +37 -0
- simtools/schemas/model_parameters/array_coordinates.schema.yml +33 -0
- simtools/schemas/model_parameters/array_coordinates_UTM.schema.yml +77 -0
- simtools/schemas/model_parameters/array_element_position_ground.schema.yml +39 -0
- simtools/schemas/model_parameters/array_element_position_utm.schema.yml +39 -0
- simtools/schemas/model_parameters/array_layouts.schema.yml +48 -0
- simtools/schemas/model_parameters/array_triggers.schema.yml +93 -0
- simtools/schemas/model_parameters/asum_clipping.schema.yml +38 -0
- simtools/schemas/model_parameters/asum_offset.schema.yml +35 -0
- simtools/schemas/model_parameters/asum_shaping.schema.yml +35 -0
- simtools/schemas/model_parameters/asum_threshold.schema.yml +38 -0
- simtools/schemas/model_parameters/atmospheric_profile.schema.yml +32 -0
- simtools/schemas/model_parameters/atmospheric_transmission.schema.yml +35 -0
- simtools/schemas/model_parameters/axes_offsets.schema.yml +53 -0
- simtools/schemas/model_parameters/camera_body_diameter.schema.yml +40 -0
- simtools/schemas/model_parameters/camera_body_shape.schema.yml +45 -0
- simtools/schemas/model_parameters/camera_config_file.schema.yml +40 -0
- simtools/schemas/model_parameters/camera_config_rotate.schema.yml +36 -0
- simtools/schemas/model_parameters/camera_degraded_efficiency.schema.yml +43 -0
- simtools/schemas/model_parameters/camera_degraded_map.schema.yml +42 -0
- simtools/schemas/model_parameters/camera_depth.schema.yml +42 -0
- simtools/schemas/model_parameters/camera_filter.schema.yml +45 -0
- simtools/schemas/model_parameters/camera_filter_incidence_angle.schema.yml +29 -0
- simtools/schemas/model_parameters/camera_pixels.schema.yml +36 -0
- simtools/schemas/model_parameters/camera_transmission.schema.yml +41 -0
- simtools/schemas/model_parameters/channels_per_chip.schema.yml +36 -0
- simtools/schemas/model_parameters/correct_nsb_spectrum_to_telescope_altitude.schema.yml +35 -0
- simtools/schemas/model_parameters/corsika_cherenkov_photon_bunch_size.schema.yml +27 -0
- simtools/schemas/model_parameters/corsika_cherenkov_photon_wavelength_range.schema.yml +38 -0
- simtools/schemas/model_parameters/corsika_first_interaction_height.schema.yml +28 -0
- simtools/schemas/model_parameters/corsika_iact_io_buffer.schema.yml +23 -0
- simtools/schemas/model_parameters/corsika_iact_max_bunches.schema.yml +27 -0
- simtools/schemas/model_parameters/corsika_iact_split_auto.schema.yml +28 -0
- simtools/schemas/model_parameters/corsika_longitudinal_shower_development.schema.yml +27 -0
- simtools/schemas/model_parameters/corsika_observation_level.schema.yml +38 -0
- simtools/schemas/model_parameters/corsika_particle_kinetic_energy_cutoff.schema.yml +52 -0
- simtools/schemas/model_parameters/corsika_starting_grammage.schema.yml +27 -0
- simtools/schemas/model_parameters/dark_events.schema.yml +32 -0
- simtools/schemas/model_parameters/default_trigger.schema.yml +35 -0
- simtools/schemas/model_parameters/design_model.schema.yml +31 -0
- simtools/schemas/model_parameters/disc_ac_coupled.schema.yml +32 -0
- simtools/schemas/model_parameters/disc_bins.schema.yml +39 -0
- simtools/schemas/model_parameters/disc_start.schema.yml +41 -0
- simtools/schemas/model_parameters/discriminator_amplitude.schema.yml +42 -0
- simtools/schemas/model_parameters/discriminator_fall_time.schema.yml +41 -0
- simtools/schemas/model_parameters/discriminator_gate_length.schema.yml +41 -0
- simtools/schemas/model_parameters/discriminator_hysteresis.schema.yml +39 -0
- simtools/schemas/model_parameters/discriminator_output_amplitude.schema.yml +40 -0
- simtools/schemas/model_parameters/discriminator_output_var_percent.schema.yml +41 -0
- simtools/schemas/model_parameters/discriminator_pulse_shape.schema.yml +33 -0
- simtools/schemas/model_parameters/discriminator_rise_time.schema.yml +42 -0
- simtools/schemas/model_parameters/discriminator_scale_threshold.schema.yml +37 -0
- simtools/schemas/model_parameters/discriminator_sigsum_over_threshold.schema.yml +44 -0
- simtools/schemas/model_parameters/discriminator_threshold.schema.yml +36 -0
- simtools/schemas/model_parameters/discriminator_time_over_threshold.schema.yml +45 -0
- simtools/schemas/model_parameters/discriminator_var_gate_length.schema.yml +40 -0
- simtools/schemas/model_parameters/discriminator_var_sigsum_over_threshold.schema.yml +41 -0
- simtools/schemas/model_parameters/discriminator_var_threshold.schema.yml +38 -0
- simtools/schemas/model_parameters/discriminator_var_time_over_threshold.schema.yml +38 -0
- simtools/schemas/model_parameters/dish_shape_length.schema.yml +41 -0
- simtools/schemas/model_parameters/dsum_clipping.schema.yml +38 -0
- simtools/schemas/model_parameters/dsum_ignore_below.schema.yml +38 -0
- simtools/schemas/model_parameters/dsum_offset.schema.yml +37 -0
- simtools/schemas/model_parameters/dsum_pedsub.schema.yml +33 -0
- simtools/schemas/model_parameters/dsum_pre_clipping.schema.yml +39 -0
- simtools/schemas/model_parameters/dsum_prescale.schema.yml +44 -0
- simtools/schemas/model_parameters/dsum_presum_max.schema.yml +38 -0
- simtools/schemas/model_parameters/dsum_presum_shift.schema.yml +45 -0
- simtools/schemas/model_parameters/dsum_shaping.schema.yml +44 -0
- simtools/schemas/model_parameters/dsum_shaping_renormalize.schema.yml +32 -0
- simtools/schemas/model_parameters/dsum_threshold.schema.yml +43 -0
- simtools/schemas/model_parameters/dsum_zero_clip.schema.yml +42 -0
- simtools/schemas/model_parameters/effective_focal_length.schema.yml +61 -0
- simtools/schemas/model_parameters/epsg_code.schema.yml +37 -0
- simtools/schemas/model_parameters/fadc_ac_coupled.schema.yml +35 -0
- simtools/schemas/model_parameters/fadc_amplitude.schema.yml +46 -0
- simtools/schemas/model_parameters/fadc_bins.schema.yml +40 -0
- simtools/schemas/model_parameters/fadc_compensate_pedestal.schema.yml +50 -0
- simtools/schemas/model_parameters/fadc_dev_pedestal.schema.yml +38 -0
- simtools/schemas/model_parameters/fadc_err_compensate_pedestal.schema.yml +42 -0
- simtools/schemas/model_parameters/fadc_err_pedestal.schema.yml +49 -0
- simtools/schemas/model_parameters/fadc_lg_amplitude.schema.yml +47 -0
- simtools/schemas/model_parameters/fadc_lg_compensate_pedestal.schema.yml +51 -0
- simtools/schemas/model_parameters/fadc_lg_dev_pedestal.schema.yml +37 -0
- simtools/schemas/model_parameters/fadc_lg_err_compensate_pedestal.schema.yml +43 -0
- simtools/schemas/model_parameters/fadc_lg_err_pedestal.schema.yml +49 -0
- simtools/schemas/model_parameters/fadc_lg_max_signal.schema.yml +43 -0
- simtools/schemas/model_parameters/fadc_lg_max_sum.schema.yml +39 -0
- simtools/schemas/model_parameters/fadc_lg_noise.schema.yml +42 -0
- simtools/schemas/model_parameters/fadc_lg_pedestal.schema.yml +40 -0
- simtools/schemas/model_parameters/fadc_lg_sensitivity.schema.yml +50 -0
- simtools/schemas/model_parameters/fadc_lg_sysvar_pedestal.schema.yml +42 -0
- simtools/schemas/model_parameters/fadc_lg_var_pedestal.schema.yml +41 -0
- simtools/schemas/model_parameters/fadc_lg_var_sensitivity.schema.yml +42 -0
- simtools/schemas/model_parameters/fadc_max_signal.schema.yml +43 -0
- simtools/schemas/model_parameters/fadc_max_sum.schema.yml +39 -0
- simtools/schemas/model_parameters/fadc_mhz.schema.yml +31 -0
- simtools/schemas/model_parameters/fadc_noise.schema.yml +41 -0
- simtools/schemas/model_parameters/fadc_pedestal.schema.yml +40 -0
- simtools/schemas/model_parameters/fadc_pulse_shape.schema.yml +39 -0
- simtools/schemas/model_parameters/fadc_sensitivity.schema.yml +50 -0
- simtools/schemas/model_parameters/fadc_sum_bins.schema.yml +43 -0
- simtools/schemas/model_parameters/fadc_sum_offset.schema.yml +43 -0
- simtools/schemas/model_parameters/fadc_sysvar_pedestal.schema.yml +42 -0
- simtools/schemas/model_parameters/fadc_var_pedestal.schema.yml +41 -0
- simtools/schemas/model_parameters/fadc_var_sensitivity.schema.yml +42 -0
- simtools/schemas/model_parameters/flatfielding.schema.yml +37 -0
- simtools/schemas/model_parameters/focal_length.schema.yml +45 -0
- simtools/schemas/model_parameters/focal_surface_parameters.schema.yml +158 -0
- simtools/schemas/model_parameters/focal_surface_ref_radius.schema.yml +29 -0
- simtools/schemas/model_parameters/focus_offset.schema.yml +66 -0
- simtools/schemas/model_parameters/gain_variation.schema.yml +43 -0
- simtools/schemas/model_parameters/geomag_horizontal.schema.yml +34 -0
- simtools/schemas/model_parameters/geomag_rotation.schema.yml +37 -0
- simtools/schemas/model_parameters/geomag_vertical.schema.yml +34 -0
- simtools/schemas/model_parameters/hg_lg_variation.schema.yml +36 -0
- simtools/schemas/model_parameters/iobuf_maximum.schema.yml +34 -0
- simtools/schemas/model_parameters/iobuf_output_maximum.schema.yml +34 -0
- simtools/schemas/model_parameters/laser_events.schema.yml +36 -0
- simtools/schemas/model_parameters/laser_external_trigger.schema.yml +35 -0
- simtools/schemas/model_parameters/laser_photons.schema.yml +32 -0
- simtools/schemas/model_parameters/laser_pulse_exptime.schema.yml +34 -0
- simtools/schemas/model_parameters/laser_pulse_offset.schema.yml +34 -0
- simtools/schemas/model_parameters/laser_pulse_sigtime.schema.yml +33 -0
- simtools/schemas/model_parameters/laser_pulse_twidth.schema.yml +33 -0
- simtools/schemas/model_parameters/laser_var_photons.schema.yml +33 -0
- simtools/schemas/model_parameters/laser_wavelength.schema.yml +33 -0
- simtools/schemas/model_parameters/led_events.schema.yml +34 -0
- simtools/schemas/model_parameters/led_photons.schema.yml +34 -0
- simtools/schemas/model_parameters/led_pulse_offset.schema.yml +32 -0
- simtools/schemas/model_parameters/led_pulse_sigtime.schema.yml +33 -0
- simtools/schemas/model_parameters/led_var_photons.schema.yml +34 -0
- simtools/schemas/model_parameters/lightguide_efficiency_vs_incidence_angle.schema.yml +41 -0
- simtools/schemas/model_parameters/lightguide_efficiency_vs_wavelength.schema.yml +43 -0
- simtools/schemas/model_parameters/min_photoelectrons.schema.yml +35 -0
- simtools/schemas/model_parameters/min_photons.schema.yml +32 -0
- simtools/schemas/model_parameters/mirror_align_random_distance.schema.yml +36 -0
- simtools/schemas/model_parameters/mirror_align_random_horizontal.schema.yml +64 -0
- simtools/schemas/model_parameters/mirror_align_random_vertical.schema.yml +64 -0
- simtools/schemas/model_parameters/mirror_class.schema.yml +41 -0
- simtools/schemas/model_parameters/mirror_degraded_reflection.schema.yml +51 -0
- simtools/schemas/model_parameters/mirror_focal_length.schema.yml +42 -0
- simtools/schemas/model_parameters/mirror_list.schema.yml +38 -0
- simtools/schemas/model_parameters/mirror_offset.schema.yml +41 -0
- simtools/schemas/model_parameters/mirror_panel_2f_measurements.schema.yml +39 -0
- simtools/schemas/model_parameters/mirror_reflection_random_angle.schema.yml +61 -0
- simtools/schemas/model_parameters/mirror_reflectivity.schema.yml +40 -0
- simtools/schemas/model_parameters/multiplicity_offset.schema.yml +46 -0
- simtools/schemas/model_parameters/nsb_autoscale_airmass.schema.yml +51 -0
- simtools/schemas/model_parameters/nsb_gain_drop_scale.schema.yml +37 -0
- simtools/schemas/model_parameters/nsb_offaxis.schema.yml +79 -0
- simtools/schemas/model_parameters/nsb_pixel_rate.schema.yml +47 -0
- simtools/schemas/model_parameters/nsb_reference_spectrum.schema.yml +34 -0
- simtools/schemas/model_parameters/nsb_reference_value.schema.yml +33 -0
- simtools/schemas/model_parameters/nsb_scaling_factor.schema.yml +35 -0
- simtools/schemas/model_parameters/nsb_skymap.schema.yml +39 -0
- simtools/schemas/model_parameters/nsb_spectrum.schema.yml +50 -0
- simtools/schemas/model_parameters/num_gains.schema.yml +34 -0
- simtools/schemas/model_parameters/only_triggered_telescopes.schema.yml +33 -0
- simtools/schemas/model_parameters/optics_properties.schema.yml +31 -0
- simtools/schemas/model_parameters/parabolic_dish.schema.yml +32 -0
- simtools/schemas/model_parameters/pedestal_events.schema.yml +32 -0
- simtools/schemas/model_parameters/photon_delay.schema.yml +38 -0
- simtools/schemas/model_parameters/photons_per_run.schema.yml +33 -0
- simtools/schemas/model_parameters/pixel_cells.schema.yml +35 -0
- simtools/schemas/model_parameters/pixels_parallel.schema.yml +54 -0
- simtools/schemas/model_parameters/pixeltrg_time_step.schema.yml +40 -0
- simtools/schemas/model_parameters/pm_average_gain.schema.yml +34 -0
- simtools/schemas/model_parameters/pm_collection_efficiency.schema.yml +40 -0
- simtools/schemas/model_parameters/pm_gain_index.schema.yml +36 -0
- simtools/schemas/model_parameters/pm_photoelectron_spectrum.schema.yml +41 -0
- simtools/schemas/model_parameters/pm_transit_time.schema.yml +63 -0
- simtools/schemas/model_parameters/pm_voltage_variation.schema.yml +39 -0
- simtools/schemas/model_parameters/primary_mirror_degraded_map.schema.yml +42 -0
- simtools/schemas/model_parameters/primary_mirror_diameter.schema.yml +33 -0
- simtools/schemas/model_parameters/primary_mirror_hole_diameter.schema.yml +33 -0
- simtools/schemas/model_parameters/primary_mirror_incidence_angle.schema.yml +29 -0
- simtools/schemas/model_parameters/primary_mirror_parameters.schema.yml +168 -0
- simtools/schemas/model_parameters/primary_mirror_ref_radius.schema.yml +36 -0
- simtools/schemas/model_parameters/primary_mirror_segmentation.schema.yml +34 -0
- simtools/schemas/model_parameters/qe_variation.schema.yml +43 -0
- simtools/schemas/model_parameters/quantum_efficiency.schema.yml +42 -0
- simtools/schemas/model_parameters/random_focal_length.schema.yml +45 -0
- simtools/schemas/model_parameters/random_generator.schema.yml +36 -0
- simtools/schemas/model_parameters/reference_point_altitude.schema.yml +35 -0
- simtools/schemas/model_parameters/reference_point_latitude.schema.yml +36 -0
- simtools/schemas/model_parameters/reference_point_longitude.schema.yml +36 -0
- simtools/schemas/model_parameters/reference_point_utm_east.schema.yml +34 -0
- simtools/schemas/model_parameters/reference_point_utm_north.schema.yml +34 -0
- simtools/schemas/model_parameters/sampled_output.schema.yml +31 -0
- simtools/schemas/model_parameters/save_pe_with_amplitude.schema.yml +34 -0
- simtools/schemas/model_parameters/secondary_mirror_baffle.schema.yml +79 -0
- simtools/schemas/model_parameters/secondary_mirror_degraded_map.schema.yml +42 -0
- simtools/schemas/model_parameters/secondary_mirror_degraded_reflection.schema.yml +41 -0
- simtools/schemas/model_parameters/secondary_mirror_diameter.schema.yml +33 -0
- simtools/schemas/model_parameters/secondary_mirror_hole_diameter.schema.yml +36 -0
- simtools/schemas/model_parameters/secondary_mirror_incidence_angle.schema.yml +29 -0
- simtools/schemas/model_parameters/secondary_mirror_parameters.schema.yml +168 -0
- simtools/schemas/model_parameters/secondary_mirror_ref_radius.schema.yml +36 -0
- simtools/schemas/model_parameters/secondary_mirror_reflectivity.schema.yml +35 -0
- simtools/schemas/model_parameters/secondary_mirror_segmentation.schema.yml +37 -0
- simtools/schemas/model_parameters/secondary_mirror_shadow_diameter.schema.yml +40 -0
- simtools/schemas/model_parameters/secondary_mirror_shadow_offset.schema.yml +40 -0
- simtools/schemas/model_parameters/store_photoelectrons.schema.yml +41 -0
- simtools/schemas/model_parameters/tailcut_scale.schema.yml +40 -0
- simtools/schemas/model_parameters/telescope_axis_height.schema.yml +31 -0
- simtools/schemas/model_parameters/telescope_random_angle.schema.yml +35 -0
- simtools/schemas/model_parameters/telescope_random_error.schema.yml +34 -0
- simtools/schemas/model_parameters/telescope_sphere_radius.schema.yml +37 -0
- simtools/schemas/model_parameters/telescope_transmission.schema.yml +113 -0
- simtools/schemas/model_parameters/teltrig_min_sigsum.schema.yml +41 -0
- simtools/schemas/model_parameters/teltrig_min_time.schema.yml +36 -0
- simtools/schemas/model_parameters/transit_time_calib_error.schema.yml +36 -0
- simtools/schemas/model_parameters/transit_time_compensate_error.schema.yml +37 -0
- simtools/schemas/model_parameters/transit_time_compensate_step.schema.yml +38 -0
- simtools/schemas/model_parameters/transit_time_error.schema.yml +45 -0
- simtools/schemas/model_parameters/transit_time_jitter.schema.yml +36 -0
- simtools/schemas/model_parameters/trigger_current_limit.schema.yml +32 -0
- simtools/schemas/model_parameters/trigger_delay_compensation.schema.yml +53 -0
- simtools/schemas/model_parameters/trigger_pixels.schema.yml +40 -0
- simtools/simtel/simtel_config_reader.py +353 -0
- simtools/simtel/simtel_config_writer.py +244 -63
- simtools/simtel/{simtel_events.py → simtel_io_events.py} +26 -25
- simtools/simtel/simtel_io_histogram.py +661 -0
- simtools/simtel/simtel_io_histograms.py +569 -0
- simtools/simtel/simulator_array.py +145 -0
- simtools/simtel/{simtel_runner_camera_efficiency.py → simulator_camera_efficiency.py} +76 -52
- simtools/simtel/simulator_light_emission.py +473 -0
- simtools/simtel/simulator_ray_tracing.py +262 -0
- simtools/simulator.py +220 -446
- simtools/testing/__init__.py +0 -0
- simtools/testing/assertions.py +151 -0
- simtools/testing/configuration.py +226 -0
- simtools/testing/helpers.py +42 -0
- simtools/testing/validate_output.py +240 -0
- simtools/utils/general.py +340 -437
- simtools/utils/geometry.py +12 -12
- simtools/utils/names.py +258 -644
- simtools/utils/value_conversion.py +176 -0
- simtools/version.py +2 -0
- simtools/visualization/legend_handlers.py +135 -152
- simtools/visualization/plot_camera.py +379 -0
- simtools/visualization/visualize.py +346 -167
- gammasimtools-0.6.1.dist-info/METADATA +0 -180
- gammasimtools-0.6.1.dist-info/RECORD +0 -91
- gammasimtools-0.6.1.dist-info/entry_points.txt +0 -23
- simtools/applications/db_development_tools/add_new_parameter_to_db.py +0 -81
- simtools/applications/db_development_tools/add_unit_to_parameter_in_db.py +0 -59
- simtools/applications/db_development_tools/mark_non_optics_parameters_non_applicable.py +0 -102
- simtools/applications/get_parameter.py +0 -92
- simtools/applications/make_regular_arrays.py +0 -160
- simtools/applications/produce_array_config.py +0 -136
- simtools/applications/production.py +0 -313
- simtools/applications/sim_showers_for_trigger_rates.py +0 -187
- simtools/applications/tune_psf.py +0 -334
- simtools/corsika/corsika_default_config.py +0 -282
- simtools/corsika/corsika_runner.py +0 -450
- simtools/corsika_simtel/corsika_simtel_runner.py +0 -197
- simtools/db_handler.py +0 -1480
- simtools/ray_tracing.py +0 -525
- simtools/simtel/simtel_histograms.py +0 -414
- simtools/simtel/simtel_runner.py +0 -244
- simtools/simtel/simtel_runner_array.py +0 -293
- simtools/simtel/simtel_runner_ray_tracing.py +0 -277
- {gammasimtools-0.6.1.dist-info → gammasimtools-0.8.1.dist-info}/LICENSE +0 -0
- {gammasimtools-0.6.1.dist-info → gammasimtools-0.8.1.dist-info}/top_level.txt +0 -0
- /simtools/{corsika_simtel → db}/__init__.py +0 -0
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/python3
|
|
2
|
+
"""Module for visualization."""
|
|
2
3
|
|
|
4
|
+
import copy
|
|
3
5
|
import logging
|
|
4
6
|
import re
|
|
5
7
|
from collections import OrderedDict
|
|
@@ -7,14 +9,13 @@ from collections import OrderedDict
|
|
|
7
9
|
import astropy.units as u
|
|
8
10
|
import matplotlib.patches as mpatches
|
|
9
11
|
import matplotlib.pyplot as plt
|
|
10
|
-
from astropy.table import QTable
|
|
12
|
+
from astropy.table import Column, QTable
|
|
11
13
|
from cycler import cycler
|
|
12
14
|
from matplotlib import gridspec
|
|
13
15
|
from matplotlib.collections import PatchCollection
|
|
14
16
|
|
|
15
17
|
from simtools.utils import geometry as transf
|
|
16
18
|
from simtools.utils import names
|
|
17
|
-
from simtools.utils.names import mst, sct
|
|
18
19
|
from simtools.visualization import legend_handlers as leg_h
|
|
19
20
|
|
|
20
21
|
__all__ = [
|
|
@@ -124,11 +125,12 @@ _logger = logging.getLogger(__name__)
|
|
|
124
125
|
|
|
125
126
|
def _add_unit(title, array):
|
|
126
127
|
"""
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
the
|
|
128
|
+
Add a unit to "title" (presumably an axis title).
|
|
129
|
+
|
|
130
|
+
The unit is extracted from the unit field of the array, in case array is an astropy quantity.
|
|
131
|
+
If a unit is found, it is added to title in the form [unit]. If a unit already is present in
|
|
132
|
+
title (in the same form), a warning is printed and no unit is added. The function assumes
|
|
133
|
+
array not to be empty and returns the modified title.
|
|
132
134
|
|
|
133
135
|
Parameters
|
|
134
136
|
----------
|
|
@@ -140,7 +142,6 @@ def _add_unit(title, array):
|
|
|
140
142
|
str
|
|
141
143
|
Title with units.
|
|
142
144
|
"""
|
|
143
|
-
|
|
144
145
|
unit = ""
|
|
145
146
|
if isinstance(array, u.Quantity):
|
|
146
147
|
unit = str(array[0].unit)
|
|
@@ -161,13 +162,14 @@ def _add_unit(title, array):
|
|
|
161
162
|
|
|
162
163
|
def set_style(palette="default", big_plot=False):
|
|
163
164
|
"""
|
|
164
|
-
|
|
165
|
-
|
|
165
|
+
Set the plotting style to homogenize plot style across the framework.
|
|
166
|
+
|
|
167
|
+
The function receives the colour palette name and whether it is a big plot or not.\
|
|
166
168
|
The latter sets the fonts and marker to be bigger in case it is a big plot. The available \
|
|
167
169
|
colour palettes are as follows:
|
|
168
170
|
|
|
169
|
-
- classic (default): A classic
|
|
170
|
-
- modified classic: Similar to the classic, with slightly different
|
|
171
|
+
- classic (default): A classic colorful palette with strong colors and contrast.
|
|
172
|
+
- modified classic: Similar to the classic, with slightly different colors.
|
|
171
173
|
- autumn: A slightly darker autumn style colour palette.
|
|
172
174
|
- purples: A pseudo sequential purple colour palette (not great for contrast).
|
|
173
175
|
- greens: A pseudo sequential green colour palette (not great for contrast).
|
|
@@ -188,15 +190,12 @@ def set_style(palette="default", big_plot=False):
|
|
|
188
190
|
KeyError
|
|
189
191
|
if provided palette does not exist.
|
|
190
192
|
"""
|
|
191
|
-
|
|
192
193
|
if palette not in COLORS:
|
|
193
194
|
raise KeyError(f"palette must be one of {', '.join(COLORS)}")
|
|
194
195
|
|
|
195
196
|
fontsize = {"default": 17, "big_plot": 30}
|
|
196
197
|
markersize = {"default": 8, "big_plot": 18}
|
|
197
|
-
plot_size = "default"
|
|
198
|
-
if big_plot:
|
|
199
|
-
plot_size = "big_plot"
|
|
198
|
+
plot_size = "big_plot" if big_plot else "default"
|
|
200
199
|
|
|
201
200
|
plt.rc("lines", linewidth=2, markersize=markersize[plot_size])
|
|
202
201
|
plt.rc(
|
|
@@ -204,9 +203,6 @@ def set_style(palette="default", big_plot=False):
|
|
|
204
203
|
prop_cycle=(
|
|
205
204
|
cycler(color=COLORS[palette]) + cycler(linestyle=LINES) + cycler(marker=MARKERS)
|
|
206
205
|
),
|
|
207
|
-
)
|
|
208
|
-
plt.rc(
|
|
209
|
-
"axes",
|
|
210
206
|
titlesize=fontsize[plot_size],
|
|
211
207
|
labelsize=fontsize[plot_size],
|
|
212
208
|
labelpad=5,
|
|
@@ -221,8 +217,9 @@ def set_style(palette="default", big_plot=False):
|
|
|
221
217
|
|
|
222
218
|
def get_colors(palette="default"):
|
|
223
219
|
"""
|
|
224
|
-
Get the colour list of the palette requested.
|
|
225
|
-
|
|
220
|
+
Get the colour list of the palette requested.
|
|
221
|
+
|
|
222
|
+
If no palette is provided, the default is returned.
|
|
226
223
|
|
|
227
224
|
Parameters
|
|
228
225
|
----------
|
|
@@ -239,7 +236,6 @@ def get_colors(palette="default"):
|
|
|
239
236
|
KeyError
|
|
240
237
|
if provided palette does not exist.
|
|
241
238
|
"""
|
|
242
|
-
|
|
243
239
|
if palette not in COLORS:
|
|
244
240
|
raise KeyError(f"palette must be one of {', '.join(COLORS)}")
|
|
245
241
|
|
|
@@ -255,7 +251,6 @@ def get_markers():
|
|
|
255
251
|
list
|
|
256
252
|
List with markers.
|
|
257
253
|
"""
|
|
258
|
-
|
|
259
254
|
return MARKERS
|
|
260
255
|
|
|
261
256
|
|
|
@@ -268,16 +263,42 @@ def get_lines():
|
|
|
268
263
|
list
|
|
269
264
|
List with line styles.
|
|
270
265
|
"""
|
|
271
|
-
|
|
272
266
|
return LINES
|
|
273
267
|
|
|
274
268
|
|
|
269
|
+
def filter_plot_kwargs(kwargs):
|
|
270
|
+
"""Filter out kwargs that are not valid for plt.plot."""
|
|
271
|
+
valid_keys = {
|
|
272
|
+
"color",
|
|
273
|
+
"linestyle",
|
|
274
|
+
"linewidth",
|
|
275
|
+
"marker",
|
|
276
|
+
"markersize",
|
|
277
|
+
"markerfacecolor",
|
|
278
|
+
"markeredgecolor",
|
|
279
|
+
"markeredgewidth",
|
|
280
|
+
"alpha",
|
|
281
|
+
"label",
|
|
282
|
+
"zorder",
|
|
283
|
+
"dashes",
|
|
284
|
+
"gapcolor",
|
|
285
|
+
"solid_capstyle",
|
|
286
|
+
"solid_joinstyle",
|
|
287
|
+
"dash_capstyle",
|
|
288
|
+
"dash_joinstyle",
|
|
289
|
+
"antialiased",
|
|
290
|
+
}
|
|
291
|
+
return {k: v for k, v in kwargs.items() if k in valid_keys}
|
|
292
|
+
|
|
293
|
+
|
|
275
294
|
def plot_1d(data, **kwargs):
|
|
276
295
|
"""
|
|
277
|
-
Produce a high contrast one dimensional plot from multiple data sets.
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
296
|
+
Produce a high contrast one dimensional plot from multiple data sets.
|
|
297
|
+
|
|
298
|
+
A ratio plot can be added at the bottom to allow easy comparison. Additional options,
|
|
299
|
+
such as plot title, plot legend, etc., are given in kwargs. Any option that can be
|
|
300
|
+
changed after plotting (e.g., axes limits, log scale, etc.) should be done using the
|
|
301
|
+
returned plt instance.
|
|
281
302
|
|
|
282
303
|
Parameters
|
|
283
304
|
----------
|
|
@@ -291,7 +312,7 @@ def plot_1d(data, **kwargs):
|
|
|
291
312
|
Choose a colour palette (see set_style for additional information).
|
|
292
313
|
* title: string
|
|
293
314
|
Set a plot title.
|
|
294
|
-
*
|
|
315
|
+
* no_legend: bool
|
|
295
316
|
Do not print a legend for the plot.
|
|
296
317
|
* big_plot: bool
|
|
297
318
|
Increase marker and font sizes (like in a wide light curve).
|
|
@@ -319,122 +340,133 @@ def plot_1d(data, **kwargs):
|
|
|
319
340
|
ValueError
|
|
320
341
|
if asked to plot a ratio or difference with just one set of data
|
|
321
342
|
"""
|
|
343
|
+
kwargs = handle_kwargs(kwargs)
|
|
344
|
+
data_dict, plot_ratio, plot_difference = prepare_data(data, kwargs)
|
|
345
|
+
fig, ax1, gs = setup_plot(kwargs, plot_ratio, plot_difference)
|
|
346
|
+
plot_args = filter_plot_kwargs(kwargs)
|
|
347
|
+
plot_main_data(data_dict, kwargs, plot_args)
|
|
348
|
+
|
|
349
|
+
if plot_ratio or plot_difference:
|
|
350
|
+
plot_ratio_difference(ax1, data_dict, plot_ratio, gs, plot_args)
|
|
351
|
+
|
|
352
|
+
if not (plot_ratio or plot_difference):
|
|
353
|
+
plt.tight_layout()
|
|
354
|
+
|
|
355
|
+
return fig
|
|
356
|
+
|
|
357
|
+
|
|
358
|
+
def handle_kwargs(kwargs):
|
|
359
|
+
"""Extract and handle keyword arguments."""
|
|
360
|
+
kwargs_defaults = {
|
|
361
|
+
"palette": "default",
|
|
362
|
+
"big_plot": False,
|
|
363
|
+
"title": "",
|
|
364
|
+
"no_legend": False,
|
|
365
|
+
"no_markers": False,
|
|
366
|
+
"empty_markers": False,
|
|
367
|
+
"plot_ratio": False,
|
|
368
|
+
"plot_difference": False,
|
|
369
|
+
}
|
|
370
|
+
for key, default in kwargs_defaults.items():
|
|
371
|
+
kwargs[key] = kwargs.pop(key, default)
|
|
322
372
|
|
|
323
|
-
|
|
324
|
-
kwargs.pop("palette", None)
|
|
325
|
-
big_plot = kwargs.get("big_plot", False)
|
|
326
|
-
kwargs.pop("big_plot", None)
|
|
327
|
-
title = kwargs.get("title", "")
|
|
328
|
-
kwargs.pop("title", None)
|
|
329
|
-
no_legend = kwargs.get("no_legend", False)
|
|
330
|
-
kwargs.pop("no_legend", None)
|
|
331
|
-
no_markers = kwargs.get("no_markers", False)
|
|
332
|
-
kwargs.pop("no_markers", None)
|
|
333
|
-
empty_markers = kwargs.get("empty_markers", False)
|
|
334
|
-
kwargs.pop("empty_markers", None)
|
|
335
|
-
|
|
336
|
-
if no_markers:
|
|
373
|
+
if kwargs["no_markers"]:
|
|
337
374
|
kwargs["marker"] = "None"
|
|
338
375
|
kwargs["linewidth"] = 4
|
|
339
|
-
if empty_markers:
|
|
376
|
+
if kwargs["empty_markers"]:
|
|
340
377
|
kwargs["markerfacecolor"] = "None"
|
|
341
|
-
kwargs.pop("empty_markers", None)
|
|
342
378
|
|
|
343
|
-
|
|
379
|
+
return kwargs
|
|
344
380
|
|
|
381
|
+
|
|
382
|
+
def prepare_data(data, kwargs):
|
|
383
|
+
"""Prepare data for plotting."""
|
|
345
384
|
if not isinstance(data, dict):
|
|
346
|
-
data_dict = {}
|
|
347
|
-
data_dict["_default"] = data
|
|
385
|
+
data_dict = {"_default": data}
|
|
348
386
|
else:
|
|
349
387
|
data_dict = data
|
|
350
388
|
|
|
351
|
-
plot_ratio
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
kwargs
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
389
|
+
if (kwargs["plot_ratio"] or kwargs["plot_difference"]) and len(data_dict) < 2:
|
|
390
|
+
raise ValueError("Asked to plot a ratio or difference with just one set of data")
|
|
391
|
+
|
|
392
|
+
return data_dict, kwargs["plot_ratio"], kwargs["plot_difference"]
|
|
393
|
+
|
|
394
|
+
|
|
395
|
+
def setup_plot(kwargs, plot_ratio, plot_difference):
|
|
396
|
+
"""Set up the plot style, figure, and gridspec."""
|
|
397
|
+
set_style(kwargs["palette"], kwargs["big_plot"])
|
|
358
398
|
|
|
359
399
|
if plot_ratio or plot_difference:
|
|
360
400
|
gs = gridspec.GridSpec(2, 1, height_ratios=[3, 1])
|
|
361
401
|
fig = plt.figure(figsize=(8, 8))
|
|
402
|
+
gs.update(hspace=0.02)
|
|
362
403
|
else:
|
|
363
404
|
gs = gridspec.GridSpec(1, 1)
|
|
364
405
|
fig = plt.figure(figsize=(8, 6))
|
|
365
406
|
|
|
366
|
-
##########################################################################################
|
|
367
|
-
# Plot the data
|
|
368
|
-
##########################################################################################
|
|
369
|
-
|
|
370
407
|
plt.subplot(gs[0])
|
|
371
408
|
ax1 = plt.gca()
|
|
372
409
|
|
|
410
|
+
return fig, ax1, gs
|
|
411
|
+
|
|
412
|
+
|
|
413
|
+
def plot_main_data(data_dict, kwargs, plot_args):
|
|
414
|
+
"""Plot the main data."""
|
|
373
415
|
for label, data_now in data_dict.items():
|
|
374
416
|
assert len(data_now.dtype.names) == 2, "Input array must have two columns with titles."
|
|
375
417
|
x_title, y_title = data_now.dtype.names[0], data_now.dtype.names[1]
|
|
376
418
|
x_title_unit = _add_unit(x_title, data_now[x_title])
|
|
377
419
|
y_title_unit = _add_unit(y_title, data_now[y_title])
|
|
378
|
-
plt.plot(data_now[x_title], data_now[y_title], label=label, **
|
|
420
|
+
plt.plot(data_now[x_title], data_now[y_title], label=label, **plot_args)
|
|
379
421
|
|
|
380
|
-
if plot_ratio or plot_difference:
|
|
381
|
-
gs.update(hspace=0.02)
|
|
382
|
-
else:
|
|
383
|
-
plt.xlabel(x_title_unit)
|
|
384
422
|
plt.ylabel(y_title_unit)
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
423
|
+
if not (kwargs["plot_ratio"] or kwargs["plot_difference"]):
|
|
424
|
+
plt.xlabel(x_title_unit)
|
|
425
|
+
if kwargs["title"]:
|
|
426
|
+
plt.title(kwargs["title"], y=1.02)
|
|
427
|
+
if "_default" not in list(data_dict.keys()) and not kwargs["no_legend"]:
|
|
389
428
|
plt.legend()
|
|
390
|
-
if not (plot_ratio or plot_difference):
|
|
391
|
-
plt.tight_layout()
|
|
392
429
|
|
|
393
|
-
##########################################################################################
|
|
394
|
-
# Plot a ratio
|
|
395
|
-
##########################################################################################
|
|
396
430
|
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
plt.plot([], [])
|
|
402
|
-
|
|
403
|
-
# Use the first entry as the reference for the ratio.
|
|
404
|
-
# If data_dict is not an OrderedDict, the reference will be random.
|
|
405
|
-
data_ref_name = next(iter(data_dict))
|
|
406
|
-
for label, data_now in data_dict.items():
|
|
407
|
-
if label == data_ref_name:
|
|
408
|
-
continue
|
|
409
|
-
x_title, y_title = data_now.dtype.names[0], data_now.dtype.names[1]
|
|
410
|
-
x_title_unit = _add_unit(x_title, data_now[x_title])
|
|
411
|
-
if plot_ratio:
|
|
412
|
-
y_values = data_now[y_title] / data_dict[data_ref_name][y_title]
|
|
413
|
-
else:
|
|
414
|
-
y_values = data_now[y_title] - data_dict[data_ref_name][y_title]
|
|
415
|
-
plt.plot(data_now[x_title], y_values, **kwargs)
|
|
431
|
+
def plot_ratio_difference(ax1, data_dict, plot_ratio, gs, plot_args):
|
|
432
|
+
"""Plot the ratio or difference plot."""
|
|
433
|
+
plt.subplot(gs[1], sharex=ax1)
|
|
434
|
+
plt.plot([], []) # Advance cycler for consistent colors/styles
|
|
416
435
|
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
if
|
|
420
|
-
|
|
421
|
-
|
|
436
|
+
data_ref_name = next(iter(data_dict))
|
|
437
|
+
for label, data_now in data_dict.items():
|
|
438
|
+
if label == data_ref_name:
|
|
439
|
+
continue
|
|
440
|
+
x_title, y_title = data_now.dtype.names[0], data_now.dtype.names[1]
|
|
441
|
+
x_title_unit = _add_unit(x_title, data_now[x_title])
|
|
442
|
+
|
|
443
|
+
if plot_ratio:
|
|
444
|
+
y_values = data_now[y_title] / data_dict[data_ref_name][y_title]
|
|
445
|
+
y_title_ratio = f"Ratio to {data_ref_name}"
|
|
446
|
+
else:
|
|
447
|
+
y_values = data_now[y_title] - data_dict[data_ref_name][y_title]
|
|
422
448
|
y_title_ratio = f"Difference to {data_ref_name}"
|
|
423
|
-
plt.ylabel(y_title_ratio)
|
|
424
449
|
|
|
425
|
-
|
|
426
|
-
nbins = min(int((ylim[1] - ylim[0]) / 0.05 + 1), 6)
|
|
427
|
-
plt.locator_params(axis="y", nbins=nbins)
|
|
450
|
+
plt.plot(data_now[x_title], y_values, **plot_args)
|
|
428
451
|
|
|
429
|
-
|
|
452
|
+
plt.xlabel(x_title_unit)
|
|
453
|
+
|
|
454
|
+
if len(y_title_ratio) > 20 and plot_ratio:
|
|
455
|
+
y_title_ratio = "Ratio"
|
|
456
|
+
|
|
457
|
+
plt.ylabel(y_title_ratio)
|
|
458
|
+
ylim = plt.gca().get_ylim()
|
|
459
|
+
nbins = min(int((ylim[1] - ylim[0]) / 0.05 + 1), 6)
|
|
460
|
+
plt.locator_params(axis="y", nbins=nbins)
|
|
430
461
|
|
|
431
462
|
|
|
432
463
|
def plot_table(table, y_title, **kwargs):
|
|
433
464
|
"""
|
|
434
|
-
Produce a high contrast one dimensional plot from the data in an astropy.Table.
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
465
|
+
Produce a high contrast one dimensional plot from the data in an astropy.Table.
|
|
466
|
+
|
|
467
|
+
A ratio plot can be added at the bottom to allow easy comparison. Additional options, such
|
|
468
|
+
as plot title, plot legend, etc., are given in kwargs. Any option that can be changed after
|
|
469
|
+
plotting (e.g., axes limits, log scale, etc.) should be done using the returned plt instance.
|
|
438
470
|
|
|
439
471
|
Parameters
|
|
440
472
|
----------
|
|
@@ -472,7 +504,6 @@ def plot_table(table, y_title, **kwargs):
|
|
|
472
504
|
ValueError
|
|
473
505
|
if table has less than two columns.
|
|
474
506
|
"""
|
|
475
|
-
|
|
476
507
|
if len(table.keys()) < 2:
|
|
477
508
|
raise ValueError("Table has to have at least two columns")
|
|
478
509
|
|
|
@@ -486,8 +517,10 @@ def plot_table(table, y_title, **kwargs):
|
|
|
486
517
|
|
|
487
518
|
def plot_hist_2d(data, **kwargs):
|
|
488
519
|
"""
|
|
489
|
-
Produce a two dimensional histogram plot.
|
|
490
|
-
|
|
520
|
+
Produce a two dimensional histogram plot.
|
|
521
|
+
|
|
522
|
+
Any option that can be changed after plotting (e.g., axes limits, log scale, etc.)
|
|
523
|
+
should be done using the returned plt instance.
|
|
491
524
|
|
|
492
525
|
Parameters
|
|
493
526
|
----------
|
|
@@ -503,7 +536,6 @@ def plot_hist_2d(data, **kwargs):
|
|
|
503
536
|
Instance of pyplot.figure in which the plot was produced.
|
|
504
537
|
|
|
505
538
|
"""
|
|
506
|
-
|
|
507
539
|
cmap = plt.cm.gist_heat_r
|
|
508
540
|
if "title" in kwargs:
|
|
509
541
|
title = kwargs["title"]
|
|
@@ -563,22 +595,22 @@ def get_telescope_patch(name, x, y, radius):
|
|
|
563
595
|
Instance of mpatches.Circle.
|
|
564
596
|
"""
|
|
565
597
|
tel_obj = leg_h.TelescopeHandler()
|
|
566
|
-
valid_name = names.
|
|
598
|
+
valid_name = names.get_array_element_type_from_name(name)
|
|
567
599
|
fill_flag = False
|
|
568
600
|
|
|
569
601
|
x = x.to(u.m)
|
|
570
602
|
y = y.to(u.m)
|
|
571
603
|
radius = radius.to(u.m)
|
|
572
604
|
|
|
573
|
-
if valid_name
|
|
605
|
+
if valid_name.startswith("MST"):
|
|
574
606
|
fill_flag = True
|
|
575
|
-
if valid_name ==
|
|
607
|
+
if valid_name == "SCTS":
|
|
576
608
|
patch = mpatches.Rectangle(
|
|
577
609
|
((x - radius / 2).value, (y - radius / 2).value),
|
|
578
610
|
width=radius.value,
|
|
579
611
|
height=radius.value,
|
|
580
612
|
fill=False,
|
|
581
|
-
color=tel_obj.colors_dict[
|
|
613
|
+
color=tel_obj.colors_dict["SCTS"],
|
|
582
614
|
)
|
|
583
615
|
else:
|
|
584
616
|
patch = mpatches.Circle(
|
|
@@ -591,10 +623,13 @@ def get_telescope_patch(name, x, y, radius):
|
|
|
591
623
|
|
|
592
624
|
|
|
593
625
|
@u.quantity_input(rotate_angle=u.deg)
|
|
594
|
-
def plot_array(
|
|
626
|
+
def plot_array(
|
|
627
|
+
telescopes, rotate_angle=0, show_tel_label=False, axes_range=None, marker_scaling=1.0
|
|
628
|
+
):
|
|
595
629
|
"""
|
|
596
|
-
Plot the array of telescopes.
|
|
597
|
-
|
|
630
|
+
Plot the array of telescopes.
|
|
631
|
+
|
|
632
|
+
The x axis gives the easting direction and y axis gives the northing direction.
|
|
598
633
|
Note that in order to convert from the CORSIKA coordinate system to the 'conventional' system
|
|
599
634
|
of North/East, a 90 degree rotation is always applied.
|
|
600
635
|
Rotation of the array elements is possible through the 'rotate_angle' given either in degrees,
|
|
@@ -604,91 +639,126 @@ def plot_array(telescopes, rotate_angle=0, show_tel_label=False):
|
|
|
604
639
|
|
|
605
640
|
Parameters
|
|
606
641
|
----------
|
|
607
|
-
telescopes:
|
|
608
|
-
|
|
609
|
-
coordinate system, i.e., the x positive axis points toward north
|
|
610
|
-
and the y positive axis points toward west.
|
|
642
|
+
telescopes: astropy.table
|
|
643
|
+
Table with the telescope position and names. Note the orientation of the axes.
|
|
611
644
|
rotate_angle:
|
|
612
645
|
Angle to rotate the plot. For rotate_angle = 0 the resulting plot will have
|
|
613
646
|
the x-axis pointing towards the east, and the y-axis pointing towards the North.
|
|
614
647
|
show_tel_label: bool
|
|
615
648
|
If True it will print the label of the individual telescopes in the plot.
|
|
616
649
|
While it works well for the smaller arrays, it gets crowded for larger arrays.
|
|
650
|
+
axes_range : float
|
|
651
|
+
Axis range for both axes. Range is from -plot_range to plot_range.
|
|
652
|
+
maker_scaling : float
|
|
653
|
+
Scaling factor for marker size to be plotted.
|
|
617
654
|
|
|
618
655
|
Returns
|
|
619
656
|
-------
|
|
620
657
|
plt.figure
|
|
621
658
|
Instance of plt.figure with the array of telescopes plotted.
|
|
622
|
-
|
|
623
659
|
"""
|
|
624
|
-
|
|
625
660
|
fig, ax = plt.subplots(1)
|
|
626
661
|
legend_objects = []
|
|
627
662
|
legend_labels = []
|
|
628
|
-
tel_counters =
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
663
|
+
tel_counters = initialize_tel_counters()
|
|
664
|
+
|
|
665
|
+
pos_x_rotated, pos_y_rotated = get_rotated_positions(telescopes, rotate_angle)
|
|
666
|
+
telescopes.add_column(Column(pos_x_rotated, name="pos_x_rotated"))
|
|
667
|
+
telescopes.add_column(Column(pos_y_rotated, name="pos_y_rotated"))
|
|
668
|
+
|
|
669
|
+
fontsize, scale = get_plot_params(len(pos_x_rotated))
|
|
670
|
+
patches = create_patches(
|
|
671
|
+
telescopes, scale, marker_scaling, show_tel_label, ax, fontsize, tel_counters
|
|
672
|
+
)
|
|
673
|
+
|
|
674
|
+
update_legend(ax, tel_counters, legend_objects, legend_labels)
|
|
675
|
+
finalize_plot(ax, patches, x_title="Easting [m]", y_title="Northing [m]", axes_range=axes_range)
|
|
676
|
+
|
|
677
|
+
return fig
|
|
635
678
|
|
|
636
|
-
pos_x_rotated, pos_y_rotated = transf.rotate(pos_x_rotated, pos_y_rotated, 90 * u.deg)
|
|
637
679
|
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
680
|
+
def initialize_tel_counters():
|
|
681
|
+
return {one_telescope: 0 for one_telescope in names.get_list_of_array_element_types()}
|
|
682
|
+
|
|
683
|
+
|
|
684
|
+
def get_rotated_positions(telescopes, rotate_angle):
|
|
685
|
+
pos_x_rotated = pos_y_rotated = None
|
|
686
|
+
if "position_x" in telescopes.colnames and "position_y" in telescopes.colnames:
|
|
687
|
+
pos_x_rotated, pos_y_rotated = telescopes["position_x"], telescopes["position_y"]
|
|
688
|
+
rotate_angle = rotate_angle + 90.0 * u.deg
|
|
689
|
+
elif "utm_east" in telescopes.colnames and "utm_north" in telescopes.colnames:
|
|
690
|
+
pos_x_rotated, pos_y_rotated = telescopes["utm_east"], telescopes["utm_north"]
|
|
641
691
|
else:
|
|
642
|
-
|
|
643
|
-
|
|
692
|
+
raise ValueError(
|
|
693
|
+
"Telescopes table must contain either 'position_x'/'position_y'"
|
|
694
|
+
"or 'utm_east'/'utm_north' columns"
|
|
695
|
+
)
|
|
696
|
+
if rotate_angle != 0:
|
|
697
|
+
pos_x_rotated, pos_y_rotated = transf.rotate(pos_x_rotated, pos_y_rotated, rotate_angle)
|
|
698
|
+
return pos_x_rotated, pos_y_rotated
|
|
699
|
+
|
|
700
|
+
|
|
701
|
+
def get_plot_params(position_length):
|
|
702
|
+
if position_length > 30:
|
|
703
|
+
return 4, 2
|
|
704
|
+
return 8, 1
|
|
644
705
|
|
|
706
|
+
|
|
707
|
+
def create_patches(telescopes, scale, marker_scaling, show_tel_label, ax, fontsize, tel_counters):
|
|
645
708
|
patches = []
|
|
646
|
-
for
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
i_tel_name = names.
|
|
709
|
+
for tel_now in telescopes:
|
|
710
|
+
telescope_name = get_telescope_name(tel_now)
|
|
711
|
+
update_tel_counters(tel_counters, telescope_name)
|
|
712
|
+
sphere_radius = get_sphere_radius(tel_now)
|
|
713
|
+
i_tel_name = names.get_array_element_type_from_name(telescope_name)
|
|
651
714
|
patches.append(
|
|
652
715
|
get_telescope_patch(
|
|
653
716
|
i_tel_name,
|
|
654
|
-
pos_x_rotated
|
|
655
|
-
pos_y_rotated
|
|
656
|
-
scale *
|
|
717
|
+
tel_now["pos_x_rotated"],
|
|
718
|
+
tel_now["pos_y_rotated"],
|
|
719
|
+
scale * sphere_radius * marker_scaling,
|
|
657
720
|
)
|
|
658
721
|
)
|
|
659
722
|
if show_tel_label:
|
|
660
723
|
ax.text(
|
|
661
|
-
pos_x_rotated
|
|
662
|
-
pos_y_rotated
|
|
663
|
-
|
|
724
|
+
tel_now["pos_x_rotated"].value,
|
|
725
|
+
tel_now["pos_y_rotated"].value + scale * sphere_radius.value,
|
|
726
|
+
telescope_name,
|
|
664
727
|
horizontalalignment="center",
|
|
665
728
|
verticalalignment="bottom",
|
|
666
729
|
fontsize=fontsize,
|
|
667
730
|
)
|
|
731
|
+
return patches
|
|
732
|
+
|
|
733
|
+
|
|
734
|
+
def get_telescope_name(tel_now):
|
|
735
|
+
"""Get the telescope name from the table row."""
|
|
736
|
+
try:
|
|
737
|
+
return tel_now["telescope_name"]
|
|
738
|
+
except KeyError:
|
|
739
|
+
return tel_now["asset_code"] + "-" + tel_now["sequence_number"]
|
|
740
|
+
|
|
741
|
+
|
|
742
|
+
def update_tel_counters(tel_counters, telescope_name):
|
|
743
|
+
"""Update the counter for the given telescope type."""
|
|
744
|
+
for tel_type in tel_counters:
|
|
745
|
+
if tel_type in telescope_name:
|
|
746
|
+
tel_counters[tel_type] += 1
|
|
747
|
+
|
|
748
|
+
|
|
749
|
+
def get_sphere_radius(tel_now):
|
|
750
|
+
"""Get the sphere radius of the telescope."""
|
|
751
|
+
return 1.0 * u.m if "sphere_radius" not in tel_now.colnames else tel_now["sphere_radius"]
|
|
668
752
|
|
|
669
|
-
|
|
753
|
+
|
|
754
|
+
def update_legend(ax, tel_counters, legend_objects, legend_labels):
|
|
755
|
+
"""Update the legend with the telescope counts."""
|
|
756
|
+
for one_telescope in names.get_list_of_array_element_types():
|
|
670
757
|
if tel_counters[one_telescope] > 0:
|
|
671
758
|
legend_objects.append(leg_h.all_telescope_objects[one_telescope]())
|
|
672
759
|
legend_labels.append(f"{one_telescope} ({tel_counters[one_telescope]})")
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
x_title = "Easting [m]"
|
|
677
|
-
y_title = "Northing [m]"
|
|
678
|
-
plt.axis("square")
|
|
679
|
-
plt.grid(True)
|
|
680
|
-
plt.gca().set_axisbelow(True)
|
|
681
|
-
plt.xlabel(x_title, fontsize=18, labelpad=0)
|
|
682
|
-
plt.ylabel(y_title, fontsize=18, labelpad=0)
|
|
683
|
-
plt.tick_params(axis="both", which="major", labelsize=15)
|
|
684
|
-
|
|
685
|
-
legend_handler_map = {
|
|
686
|
-
list(leg_h.legend_handler_map.keys())[i_key]: list(leg_h.legend_handler_map.values())[
|
|
687
|
-
i_key
|
|
688
|
-
]()
|
|
689
|
-
for i_key, _ in enumerate(leg_h.legend_handler_map)
|
|
690
|
-
}
|
|
691
|
-
plt.legend(
|
|
760
|
+
legend_handler_map = {k: v() for k, v in leg_h.legend_handler_map.items()}
|
|
761
|
+
ax.legend(
|
|
692
762
|
legend_objects,
|
|
693
763
|
legend_labels,
|
|
694
764
|
handler_map=legend_handler_map,
|
|
@@ -696,6 +766,115 @@ def plot_array(telescopes, rotate_angle=0, show_tel_label=False):
|
|
|
696
766
|
loc="best",
|
|
697
767
|
)
|
|
698
768
|
|
|
769
|
+
|
|
770
|
+
def finalize_plot(ax, patches, x_title, y_title, axes_range):
|
|
771
|
+
"""Finalize the plot by adding titles, setting limits, and adding patches."""
|
|
772
|
+
ax.add_collection(PatchCollection(patches, match_original=True))
|
|
773
|
+
ax.set_xlabel(x_title, fontsize=12, labelpad=0)
|
|
774
|
+
ax.set_ylabel(y_title, fontsize=12, labelpad=0)
|
|
775
|
+
ax.tick_params(axis="both", which="major", labelsize=8)
|
|
776
|
+
ax.set_axisbelow(True)
|
|
777
|
+
ax.axis("square")
|
|
778
|
+
if axes_range is not None:
|
|
779
|
+
ax.set_xlim(-axes_range, axes_range)
|
|
780
|
+
ax.set_ylim(-axes_range, axes_range)
|
|
699
781
|
plt.tight_layout()
|
|
700
782
|
|
|
783
|
+
|
|
784
|
+
def plot_simtel_ctapipe(filename, cleaning_args, distance, return_cleaned=False):
|
|
785
|
+
"""
|
|
786
|
+
Read in a simtel file and plots reconstructed photoelectrons via ctapipe.
|
|
787
|
+
|
|
788
|
+
Parameters
|
|
789
|
+
----------
|
|
790
|
+
filename : str
|
|
791
|
+
Path to the simtel file.
|
|
792
|
+
cleaning_args : tuple, optional
|
|
793
|
+
Cleaning parameters as (boundary_thresh, picture_thresh, min_number_picture_neighbors).
|
|
794
|
+
distance : astropy Quantity, optional
|
|
795
|
+
Distance to the target.
|
|
796
|
+
return_cleaned : bool, optional
|
|
797
|
+
If True, apply cleaning to the image.
|
|
798
|
+
|
|
799
|
+
Returns
|
|
800
|
+
-------
|
|
801
|
+
fig : matplotlib.figure.Figure
|
|
802
|
+
The matplotlib figure containing the plot.
|
|
803
|
+
"""
|
|
804
|
+
# pylint:disable=import-outside-toplevel
|
|
805
|
+
import numpy as np
|
|
806
|
+
from ctapipe.calib import CameraCalibrator
|
|
807
|
+
from ctapipe.image import tailcuts_clean
|
|
808
|
+
from ctapipe.io import EventSource
|
|
809
|
+
from ctapipe.visualization import CameraDisplay
|
|
810
|
+
|
|
811
|
+
default_cleaning_levels = {
|
|
812
|
+
"CHEC": (2, 4, 2),
|
|
813
|
+
"LSTCam": (3.5, 7, 2),
|
|
814
|
+
"FlashCam": (3.5, 7, 2),
|
|
815
|
+
"NectarCam": (4, 8, 2),
|
|
816
|
+
}
|
|
817
|
+
|
|
818
|
+
source = EventSource(filename, max_events=1)
|
|
819
|
+
event = None
|
|
820
|
+
events = [copy.deepcopy(event) for event in source]
|
|
821
|
+
if len(events) > 1:
|
|
822
|
+
event = events[-1]
|
|
823
|
+
else:
|
|
824
|
+
try:
|
|
825
|
+
event = events[0]
|
|
826
|
+
except IndexError:
|
|
827
|
+
event = events
|
|
828
|
+
tel_id = sorted(event.r1.tel.keys())[0]
|
|
829
|
+
|
|
830
|
+
calib = CameraCalibrator(subarray=source.subarray)
|
|
831
|
+
calib(event)
|
|
832
|
+
|
|
833
|
+
geometry = source.subarray.tel[1].camera.geometry
|
|
834
|
+
image = event.dl1.tel[tel_id].image
|
|
835
|
+
cleaned = image.copy()
|
|
836
|
+
|
|
837
|
+
if return_cleaned:
|
|
838
|
+
if cleaning_args is None:
|
|
839
|
+
boundary, picture, min_neighbors = default_cleaning_levels[geometry.name]
|
|
840
|
+
else:
|
|
841
|
+
boundary, picture, min_neighbors = cleaning_args
|
|
842
|
+
mask = tailcuts_clean(
|
|
843
|
+
geometry,
|
|
844
|
+
image,
|
|
845
|
+
picture_thresh=picture,
|
|
846
|
+
boundary_thresh=boundary,
|
|
847
|
+
min_number_picture_neighbors=min_neighbors,
|
|
848
|
+
)
|
|
849
|
+
cleaned[~mask] = 0
|
|
850
|
+
|
|
851
|
+
fig, ax = plt.subplots(dpi=300)
|
|
852
|
+
title = f"CT{tel_id}, run {event.index.obs_id} event {event.index.event_id}"
|
|
853
|
+
disp = CameraDisplay(geometry, image=cleaned, norm="symlog", ax=ax)
|
|
854
|
+
disp.cmap = "RdBu_r"
|
|
855
|
+
disp.add_colorbar(fraction=0.02, pad=-0.1)
|
|
856
|
+
disp.set_limits_percent(100)
|
|
857
|
+
ax.set_title(title, pad=20)
|
|
858
|
+
ax.annotate(
|
|
859
|
+
f"tel type: {source.subarray.tel[1].type.name}\n"
|
|
860
|
+
f"optics: {source.subarray.tel[1].optics.name}\n"
|
|
861
|
+
f"camera: {source.subarray.tel[1].camera_name}\n"
|
|
862
|
+
f"distance: {distance.to(u.m)}",
|
|
863
|
+
xy=(0, 0),
|
|
864
|
+
xytext=(0.1, 1),
|
|
865
|
+
xycoords="axes fraction",
|
|
866
|
+
va="top",
|
|
867
|
+
size=7,
|
|
868
|
+
)
|
|
869
|
+
ax.annotate(
|
|
870
|
+
f"dl1 image,\ntotal $p.e._{{reco}}$: {np.round(np.sum(image))}\n",
|
|
871
|
+
xy=(0, 0),
|
|
872
|
+
xytext=(0.75, 1),
|
|
873
|
+
xycoords="axes fraction",
|
|
874
|
+
va="top",
|
|
875
|
+
ha="left",
|
|
876
|
+
size=7,
|
|
877
|
+
)
|
|
878
|
+
ax.set_axis_off()
|
|
879
|
+
fig.tight_layout()
|
|
701
880
|
return fig
|