gammasimtools 0.6.0__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.0.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 +329 -533
- 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 -496
- simtools/model/mirrors.py +61 -44
- simtools/model/model_parameter.py +602 -0
- simtools/model/model_utils.py +7 -103
- 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 +266 -568
- 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.0.dist-info/METADATA +0 -180
- gammasimtools-0.6.0.dist-info/RECORD +0 -91
- gammasimtools-0.6.0.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 -1481
- 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.0.dist-info → gammasimtools-0.8.1.dist-info}/LICENSE +0 -0
- {gammasimtools-0.6.0.dist-info → gammasimtools-0.8.1.dist-info}/top_level.txt +0 -0
- /simtools/{corsika_simtel → db}/__init__.py +0 -0
simtools/layout/array_layout.py
CHANGED
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
"""Prepare layout for coordinate transformations."""
|
|
2
|
+
|
|
3
|
+
import json
|
|
1
4
|
import logging
|
|
2
5
|
from pathlib import Path
|
|
3
6
|
|
|
@@ -5,22 +8,23 @@ import astropy.units as u
|
|
|
5
8
|
import numpy as np
|
|
6
9
|
from astropy.table import QTable
|
|
7
10
|
|
|
8
|
-
|
|
11
|
+
import simtools.utils.general as gen
|
|
9
12
|
from simtools.data_model import data_reader
|
|
10
13
|
from simtools.io_operations import io_handler
|
|
11
14
|
from simtools.layout.geo_coordinates import GeoCoordinates
|
|
12
15
|
from simtools.layout.telescope_position import TelescopePosition
|
|
13
|
-
from simtools.
|
|
14
|
-
from simtools.
|
|
16
|
+
from simtools.model.site_model import SiteModel
|
|
17
|
+
from simtools.model.telescope_model import TelescopeModel
|
|
18
|
+
from simtools.utils import names, value_conversion
|
|
15
19
|
|
|
16
|
-
__all__ = ["
|
|
20
|
+
__all__ = ["ArrayLayout", "InvalidTelescopeListFileError"]
|
|
17
21
|
|
|
18
22
|
|
|
19
|
-
class
|
|
23
|
+
class InvalidTelescopeListFileError(Exception):
|
|
20
24
|
"""Exception for invalid telescope list file."""
|
|
21
25
|
|
|
22
26
|
|
|
23
|
-
class
|
|
27
|
+
class InvalidCoordinateDataTypeError(Exception):
|
|
24
28
|
"""Exception for low-precision coordinate data type."""
|
|
25
29
|
|
|
26
30
|
|
|
@@ -34,334 +38,139 @@ class ArrayLayout:
|
|
|
34
38
|
MongoDB configuration.
|
|
35
39
|
site: str
|
|
36
40
|
Site name or location (e.g., North/South or LaPalma/Paranal)
|
|
41
|
+
model_version: str
|
|
42
|
+
Version of the model (e.g., 6.0.0).
|
|
37
43
|
label: str
|
|
38
44
|
Instance label.
|
|
39
45
|
name: str
|
|
40
46
|
Name of the layout.
|
|
41
|
-
layout_center_data: dict
|
|
42
|
-
Dict describing array center coordinates.
|
|
43
|
-
corsika_telescope_data: dict
|
|
44
|
-
Dict describing CORSIKA telescope parameters.
|
|
45
47
|
telescope_list_file: str or Path
|
|
46
48
|
Path to the telescope list file.
|
|
49
|
+
telescope_list_metadata_file: str or Path
|
|
50
|
+
Path to telescope list metadata (if not part of telescope_list_file)
|
|
51
|
+
validate: bool
|
|
52
|
+
Validate input file list.
|
|
47
53
|
"""
|
|
48
54
|
|
|
49
55
|
def __init__(
|
|
50
56
|
self,
|
|
51
|
-
mongo_db_config
|
|
52
|
-
site
|
|
57
|
+
mongo_db_config,
|
|
58
|
+
site,
|
|
59
|
+
model_version,
|
|
53
60
|
label=None,
|
|
54
61
|
name=None,
|
|
55
|
-
layout_center_data=None,
|
|
56
|
-
corsika_telescope_data=None,
|
|
57
62
|
telescope_list_file=None,
|
|
58
63
|
telescope_list_metadata_file=None,
|
|
59
64
|
validate=False,
|
|
60
65
|
):
|
|
61
|
-
"""
|
|
62
|
-
Initialize ArrayLayout.
|
|
63
|
-
"""
|
|
64
|
-
|
|
66
|
+
"""Initialize ArrayLayout."""
|
|
65
67
|
self._logger = logging.getLogger(__name__)
|
|
66
68
|
|
|
67
|
-
self.
|
|
69
|
+
self.model_version = model_version
|
|
68
70
|
self.label = label
|
|
69
71
|
self.name = name
|
|
72
|
+
self.mongo_db_config = mongo_db_config
|
|
70
73
|
self.site = None if site is None else names.validate_site_name(site)
|
|
74
|
+
self.site_model = None
|
|
71
75
|
self.io_handler = io_handler.IOHandler()
|
|
72
76
|
self.geo_coordinates = GeoCoordinates()
|
|
73
77
|
|
|
74
|
-
self.telescope_list_file = None
|
|
75
78
|
self._telescope_list = []
|
|
76
|
-
self.
|
|
79
|
+
self._corsika_observation_level = None
|
|
80
|
+
self._reference_position_dict = {}
|
|
81
|
+
self._array_center = None
|
|
77
82
|
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
self.initialize_array_layout_from_telescope_file(
|
|
83
|
-
telescope_list_file=telescope_list_file,
|
|
84
|
-
telescope_list_metadata_file=telescope_list_metadata_file,
|
|
85
|
-
validate=validate,
|
|
86
|
-
)
|
|
87
|
-
|
|
88
|
-
@classmethod
|
|
89
|
-
def from_array_layout_name(cls, mongo_db_config, array_layout_name, label=None):
|
|
90
|
-
"""
|
|
91
|
-
Read telescope list from file for given layout name (e.g. South-4LST, North-Prod5, ...).
|
|
92
|
-
Layout definitions are given in the `data/layout` path.
|
|
93
|
-
|
|
94
|
-
Parameters
|
|
95
|
-
----------
|
|
96
|
-
mongo_db_config: dict
|
|
97
|
-
MongoDB configuration.
|
|
98
|
-
array_layout_name: str
|
|
99
|
-
e.g. South-4LST, North-Prod5 ...
|
|
100
|
-
label: str
|
|
101
|
-
Instance label. Important for output file naming.
|
|
102
|
-
|
|
103
|
-
Returns
|
|
104
|
-
-------
|
|
105
|
-
ArrayLayout
|
|
106
|
-
Instance of the ArrayLayout.
|
|
107
|
-
"""
|
|
108
|
-
|
|
109
|
-
split_name = array_layout_name.split("-")
|
|
110
|
-
site_name = names.validate_site_name(split_name[0])
|
|
111
|
-
array_name = names.validate_array_layout_name(split_name[1])
|
|
112
|
-
valid_array_layout_name = site_name + "-" + array_name
|
|
113
|
-
|
|
114
|
-
layout = cls(
|
|
115
|
-
site=site_name,
|
|
116
|
-
mongo_db_config=mongo_db_config,
|
|
117
|
-
name=valid_array_layout_name,
|
|
118
|
-
label=label,
|
|
119
|
-
)
|
|
120
|
-
|
|
121
|
-
telescope_list_file = layout.io_handler.get_input_data_file(
|
|
122
|
-
"layout", f"telescope_positions-{valid_array_layout_name}.ecsv"
|
|
83
|
+
self._initialize_array_layout(
|
|
84
|
+
telescope_list_file=telescope_list_file,
|
|
85
|
+
telescope_list_metadata_file=telescope_list_metadata_file,
|
|
86
|
+
validate=validate,
|
|
123
87
|
)
|
|
124
|
-
layout.initialize_array_layout_from_telescope_file(telescope_list_file)
|
|
125
|
-
|
|
126
|
-
return layout
|
|
127
88
|
|
|
128
89
|
def __len__(self):
|
|
129
|
-
"""
|
|
130
|
-
Return number of telescopes in the layout.
|
|
131
|
-
"""
|
|
90
|
+
"""Return number of telescopes in the layout."""
|
|
132
91
|
return len(self._telescope_list)
|
|
133
92
|
|
|
134
93
|
def __getitem__(self, i):
|
|
135
|
-
"""
|
|
136
|
-
Return telescope at list position i.
|
|
137
|
-
|
|
138
|
-
"""
|
|
94
|
+
"""Return telescope at list position i."""
|
|
139
95
|
return self._telescope_list[i]
|
|
140
96
|
|
|
141
|
-
def
|
|
142
|
-
"""
|
|
143
|
-
Initialize
|
|
144
|
-
(dictionary, yaml, ecsv header), which require checks to handle units correctly.
|
|
145
|
-
|
|
146
|
-
Parameters
|
|
147
|
-
----------
|
|
148
|
-
corsika_dict dict
|
|
149
|
-
dictionary with CORSIKA telescope parameters
|
|
150
|
-
|
|
151
|
-
"""
|
|
152
|
-
self._corsika_telescope = {}
|
|
153
|
-
|
|
154
|
-
if corsika_dict is None:
|
|
155
|
-
self._logger.debug("Initialize CORSIKA telescope parameters from file")
|
|
156
|
-
corsika_dict = self._from_corsika_file_to_dict()
|
|
157
|
-
else:
|
|
158
|
-
self._logger.debug(f"Initialize CORSIKA telescope parameters from dict: {corsika_dict}")
|
|
159
|
-
|
|
160
|
-
self._initialize_corsika_telescope_from_dict(corsika_dict)
|
|
161
|
-
|
|
162
|
-
def _from_corsika_file_to_dict(self, file_name=None):
|
|
163
|
-
"""
|
|
164
|
-
Get the corsika parameter file and return a dictionary with the keys necessary to
|
|
165
|
-
initialize this class.
|
|
166
|
-
|
|
167
|
-
Parameters
|
|
168
|
-
----------
|
|
169
|
-
file_name: str or Path
|
|
170
|
-
File from which to extract the corsika parameters. Default is
|
|
171
|
-
data/parameters/corsika_parameters.yml
|
|
172
|
-
|
|
173
|
-
Returns
|
|
174
|
-
------
|
|
175
|
-
corsika_dict:
|
|
176
|
-
Dictionary with corsika telescopes information.
|
|
177
|
-
|
|
178
|
-
Raises
|
|
179
|
-
------
|
|
180
|
-
FileNotFoundError:
|
|
181
|
-
If file_name does not exist.
|
|
182
|
-
"""
|
|
183
|
-
if file_name is None:
|
|
184
|
-
try:
|
|
185
|
-
corsika_parameters_dict = collect_data_from_file_or_dict(
|
|
186
|
-
self.io_handler.get_input_data_file("parameters", "corsika_parameters.yml"),
|
|
187
|
-
None,
|
|
188
|
-
)
|
|
189
|
-
except io_handler.IncompleteIOHandlerInit:
|
|
190
|
-
self._logger.info("Error reading CORSIKA parameters from file")
|
|
191
|
-
return {}
|
|
192
|
-
else:
|
|
193
|
-
if not isinstance(file_name, Path):
|
|
194
|
-
file_name = Path(file_name)
|
|
195
|
-
if file_name.exists():
|
|
196
|
-
corsika_parameters_dict = collect_data_from_file_or_dict(file_name, None)
|
|
197
|
-
else:
|
|
198
|
-
raise FileNotFoundError
|
|
199
|
-
|
|
200
|
-
corsika_dict = {}
|
|
201
|
-
corsika_pars = ["corsika_sphere_radius", "corsika_sphere_center"]
|
|
202
|
-
for simtools_par in corsika_pars:
|
|
203
|
-
corsika_par = names.translate_simtools_to_corsika(simtools_par)
|
|
204
|
-
corsika_dict[simtools_par] = {}
|
|
205
|
-
for key, value in corsika_parameters_dict[corsika_par].items():
|
|
206
|
-
corsika_dict[simtools_par][key] = value["value"]
|
|
207
|
-
try:
|
|
208
|
-
unit = value["unit"]
|
|
209
|
-
corsika_dict[simtools_par][key] = corsika_dict[simtools_par][key] * u.Unit(unit)
|
|
210
|
-
except KeyError:
|
|
211
|
-
self._logger.warning(
|
|
212
|
-
"Key not valid. Dictionary does not have a key 'unit'. Continuing without "
|
|
213
|
-
"the unit."
|
|
214
|
-
)
|
|
215
|
-
|
|
97
|
+
def _initialize_site_parameters_from_db(self):
|
|
98
|
+
"""Initialize site parameters required for transformations using the database."""
|
|
99
|
+
self._logger.debug("Initialize parameters from DB")
|
|
216
100
|
if self.mongo_db_config is None:
|
|
217
|
-
|
|
218
|
-
raise ValueError
|
|
219
|
-
if self.site is None:
|
|
220
|
-
self._logger.error("Site was not provided, cannot set site altitude")
|
|
221
|
-
raise ValueError
|
|
222
|
-
|
|
223
|
-
db = db_handler.DatabaseHandler(mongo_db_config=self.mongo_db_config)
|
|
224
|
-
self._logger.debug("Reading site parameters from DB")
|
|
225
|
-
_site_pars = db.get_site_parameters(self.site, "Released", only_applicable=True)
|
|
226
|
-
corsika_dict["corsika_obs_level"] = _site_pars["altitude"]["Value"] * u.Unit(
|
|
227
|
-
_site_pars["altitude"]["units"]
|
|
228
|
-
)
|
|
229
|
-
|
|
230
|
-
return corsika_dict
|
|
231
|
-
|
|
232
|
-
def _initialize_sphere_parameters(self, sphere_dict):
|
|
233
|
-
"""
|
|
234
|
-
Set CORSIKA sphere parameters from dictionary. Type of input varies and depend on data \
|
|
235
|
-
source for these parameters.
|
|
236
|
-
|
|
237
|
-
Example for sphere_dict: {LST: 12.5 m, MST: 9.15 m, SST: 3 m}
|
|
238
|
-
|
|
239
|
-
Parameters
|
|
240
|
-
----------
|
|
241
|
-
sphere_dict: dict
|
|
242
|
-
dictionary with sphere parameters
|
|
243
|
-
|
|
244
|
-
Returns
|
|
245
|
-
-------
|
|
246
|
-
dict
|
|
247
|
-
dictionary with sphere parameters.
|
|
248
|
-
|
|
249
|
-
"""
|
|
250
|
-
|
|
251
|
-
_sphere_dict_cleaned = {}
|
|
252
|
-
try:
|
|
253
|
-
for key, value in sphere_dict.items():
|
|
254
|
-
if isinstance(value, (str, u.Quantity)):
|
|
255
|
-
_sphere_dict_cleaned[key] = u.Quantity(value)
|
|
256
|
-
else:
|
|
257
|
-
_sphere_dict_cleaned[key] = value["value"] * u.Unit(value["unit"])
|
|
258
|
-
except (TypeError, KeyError) as exc:
|
|
259
|
-
self._logger.error(f"Error setting CORSIKA sphere parameters from {sphere_dict}")
|
|
260
|
-
raise exc
|
|
261
|
-
|
|
262
|
-
return _sphere_dict_cleaned
|
|
101
|
+
raise ValueError("No database configuration provided")
|
|
263
102
|
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
""
|
|
274
|
-
|
|
275
|
-
try:
|
|
276
|
-
self._corsika_telescope["corsika_obs_level"] = u.Quantity(
|
|
277
|
-
corsika_dict["corsika_obs_level"]
|
|
278
|
-
)
|
|
279
|
-
except (TypeError, KeyError):
|
|
280
|
-
self._corsika_telescope["corsika_obs_level"] = np.nan * u.m
|
|
281
|
-
|
|
282
|
-
for key in ["corsika_sphere_center", "corsika_sphere_radius"]:
|
|
283
|
-
try:
|
|
284
|
-
self._corsika_telescope[key] = self._initialize_sphere_parameters(corsika_dict[key])
|
|
285
|
-
except (TypeError, KeyError):
|
|
286
|
-
pass
|
|
103
|
+
self.site_model = SiteModel(
|
|
104
|
+
site=self.site,
|
|
105
|
+
model_version=self.model_version,
|
|
106
|
+
mongo_db_config=self.mongo_db_config,
|
|
107
|
+
)
|
|
108
|
+
self._corsika_observation_level = self.site_model.get_corsika_site_parameters().get(
|
|
109
|
+
"corsika_observation_level", None
|
|
110
|
+
)
|
|
111
|
+
self._reference_position_dict = self.site_model.get_reference_point()
|
|
112
|
+
self._logger.debug(f"Reference point: {self._reference_position_dict}")
|
|
287
113
|
|
|
288
|
-
def _initialize_coordinate_systems(self
|
|
114
|
+
def _initialize_coordinate_systems(self):
|
|
289
115
|
"""
|
|
290
116
|
Initialize array center and coordinate systems.
|
|
117
|
+
|
|
291
118
|
By definition, the array center is at (0,0) in
|
|
292
119
|
the ground coordinate system.
|
|
293
120
|
|
|
294
|
-
Parameters
|
|
295
|
-
----------
|
|
296
|
-
center_dict: dict
|
|
297
|
-
dictionary with coordinates of array center.
|
|
298
|
-
|
|
299
121
|
Raises
|
|
300
122
|
------
|
|
301
123
|
TypeError
|
|
302
124
|
invalid array center definition.
|
|
303
125
|
|
|
304
126
|
"""
|
|
305
|
-
|
|
306
|
-
center_dict = {} if center_dict is None else center_dict
|
|
307
|
-
|
|
308
127
|
self._array_center = TelescopePosition()
|
|
309
128
|
self._array_center.name = "array_center"
|
|
310
|
-
self._array_center.set_coordinates("ground", 0.0 * u.m, 0.0 * u.m
|
|
311
|
-
self.
|
|
312
|
-
self.
|
|
313
|
-
|
|
314
|
-
|
|
129
|
+
self._array_center.set_coordinates("ground", 0.0 * u.m, 0.0 * u.m)
|
|
130
|
+
self._set_array_center_utm()
|
|
131
|
+
self._array_center.set_altitude(
|
|
132
|
+
u.Quantity(self._reference_position_dict.get("center_altitude", np.nan * u.m))
|
|
133
|
+
)
|
|
134
|
+
_name = self._reference_position_dict.get("array_name")
|
|
315
135
|
self.name = _name if _name is not None else self.name
|
|
316
136
|
|
|
137
|
+
self._logger.debug(f"Initialized array center at UTM {self._reference_position_dict}")
|
|
317
138
|
self._array_center.convert_all(
|
|
318
139
|
crs_local=self.geo_coordinates.crs_local(self._array_center),
|
|
319
140
|
crs_wgs84=self.geo_coordinates.crs_wgs84(),
|
|
320
|
-
crs_utm=self.geo_coordinates.crs_utm(
|
|
141
|
+
crs_utm=self.geo_coordinates.crs_utm(
|
|
142
|
+
self._reference_position_dict.get("epsg_code", None)
|
|
143
|
+
),
|
|
321
144
|
)
|
|
322
145
|
|
|
323
|
-
def
|
|
324
|
-
"""
|
|
325
|
-
Set array center coordinates in mercator system.
|
|
326
|
-
|
|
327
|
-
"""
|
|
328
|
-
|
|
329
|
-
try:
|
|
330
|
-
self._array_center.set_coordinates(
|
|
331
|
-
"mercator",
|
|
332
|
-
u.Quantity(center_dict.get("center_lat", np.nan * u.deg)),
|
|
333
|
-
u.Quantity(center_dict.get("center_lon", np.nan * u.deg)),
|
|
334
|
-
)
|
|
335
|
-
except TypeError:
|
|
336
|
-
pass
|
|
337
|
-
|
|
338
|
-
def _set_array_center_utm(self, center_dict):
|
|
146
|
+
def _set_array_center_utm(self):
|
|
339
147
|
"""
|
|
340
148
|
Set array center coordinates in UTM system.
|
|
149
|
+
|
|
341
150
|
Convert array center position to WGS84 system
|
|
342
151
|
(as latitudes are required for the definition
|
|
343
152
|
for the definition of the ground coordinate system)
|
|
344
153
|
|
|
345
154
|
"""
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
self.
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
self.
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
except TypeError:
|
|
359
|
-
pass
|
|
155
|
+
self._array_center.set_coordinates(
|
|
156
|
+
"utm",
|
|
157
|
+
u.Quantity(self._reference_position_dict.get("center_easting", np.nan * u.m)),
|
|
158
|
+
u.Quantity(self._reference_position_dict.get("center_northing", np.nan * u.m)),
|
|
159
|
+
)
|
|
160
|
+
self._array_center.convert_all(
|
|
161
|
+
crs_local=None,
|
|
162
|
+
crs_wgs84=self.geo_coordinates.crs_wgs84(),
|
|
163
|
+
crs_utm=self.geo_coordinates.crs_utm(
|
|
164
|
+
self._reference_position_dict.get("epsg_code", None)
|
|
165
|
+
),
|
|
166
|
+
)
|
|
360
167
|
|
|
361
|
-
def _altitude_from_corsika_z(self, pos_z=None, altitude=None,
|
|
168
|
+
def _altitude_from_corsika_z(self, pos_z=None, altitude=None, telescope_axis_height=None):
|
|
362
169
|
"""
|
|
363
|
-
Calculate altitude
|
|
364
|
-
|
|
170
|
+
Calculate altitude.
|
|
171
|
+
|
|
172
|
+
The value is calculated from CORSIKA z-coordinate (if pos_z is given) or CORSIKA
|
|
173
|
+
z-coordinate from altitude (if altitude is given).
|
|
365
174
|
|
|
366
175
|
Parameters
|
|
367
176
|
----------
|
|
@@ -369,8 +178,8 @@ class ArrayLayout:
|
|
|
369
178
|
CORSIKA z-coordinate of telescope in equivalent units of meter.
|
|
370
179
|
altitude: astropy.Quantity
|
|
371
180
|
Telescope altitude in equivalent units of meter.
|
|
372
|
-
|
|
373
|
-
Telescope
|
|
181
|
+
tel_axis_height: astropy.Quantity
|
|
182
|
+
Telescope axis height in equivalent units of meter.
|
|
374
183
|
|
|
375
184
|
Returns
|
|
376
185
|
-------
|
|
@@ -378,54 +187,27 @@ class ArrayLayout:
|
|
|
378
187
|
Altitude or CORSIKA z-coordinate (np.nan in case of ill-defined value).
|
|
379
188
|
|
|
380
189
|
"""
|
|
190
|
+
self._logger.debug(
|
|
191
|
+
f"pos_z: {pos_z}, altitude: {altitude}, "
|
|
192
|
+
f"axis_height: {telescope_axis_height}, "
|
|
193
|
+
f"obs_level: {self._corsika_observation_level}"
|
|
194
|
+
)
|
|
195
|
+
|
|
381
196
|
if pos_z is not None and altitude is None:
|
|
382
197
|
return TelescopePosition.convert_telescope_altitude_from_corsika_system(
|
|
383
198
|
pos_z,
|
|
384
|
-
self.
|
|
385
|
-
|
|
199
|
+
self._corsika_observation_level,
|
|
200
|
+
telescope_axis_height,
|
|
386
201
|
)
|
|
387
202
|
|
|
388
203
|
if altitude is not None and pos_z is None:
|
|
389
204
|
return TelescopePosition.convert_telescope_altitude_to_corsika_system(
|
|
390
205
|
altitude,
|
|
391
|
-
self.
|
|
392
|
-
|
|
206
|
+
self._corsika_observation_level,
|
|
207
|
+
telescope_axis_height,
|
|
393
208
|
)
|
|
394
209
|
return np.nan
|
|
395
210
|
|
|
396
|
-
def _get_corsika_sphere_center(self, tel_name):
|
|
397
|
-
"""
|
|
398
|
-
Return CORSIKA sphere center value for given telescope.
|
|
399
|
-
|
|
400
|
-
Parameters
|
|
401
|
-
----------
|
|
402
|
-
tel_name: str
|
|
403
|
-
Telescope Name.
|
|
404
|
-
|
|
405
|
-
Returns
|
|
406
|
-
-------
|
|
407
|
-
astropy.Quantity
|
|
408
|
-
Telescope sphere center value (0.0*u.m if sphere center is not defined).
|
|
409
|
-
|
|
410
|
-
Raises
|
|
411
|
-
------
|
|
412
|
-
KeyError
|
|
413
|
-
if Missing definition of CORSIKA sphere center for this telescope type.
|
|
414
|
-
|
|
415
|
-
"""
|
|
416
|
-
|
|
417
|
-
try:
|
|
418
|
-
return self._corsika_telescope["corsika_sphere_center"][
|
|
419
|
-
names.get_telescope_type(tel_name)
|
|
420
|
-
]
|
|
421
|
-
except KeyError:
|
|
422
|
-
self._logger.warning(
|
|
423
|
-
"Missing definition of CORSIKA sphere center for telescope "
|
|
424
|
-
f"{tel_name} of type {names.get_telescope_type(tel_name)}"
|
|
425
|
-
)
|
|
426
|
-
|
|
427
|
-
return 0.0 * u.m
|
|
428
|
-
|
|
429
211
|
def _load_telescope_names(self, row):
|
|
430
212
|
"""
|
|
431
213
|
Read and set telescope names.
|
|
@@ -442,16 +224,19 @@ class ArrayLayout:
|
|
|
442
224
|
|
|
443
225
|
Raises
|
|
444
226
|
------
|
|
445
|
-
|
|
227
|
+
InvalidTelescopeListFileError
|
|
446
228
|
in case neither telescope name or asset_code / sequence number are given.
|
|
447
229
|
|
|
448
230
|
"""
|
|
449
|
-
|
|
450
231
|
tel = TelescopePosition()
|
|
451
232
|
try:
|
|
452
233
|
tel.name = row["telescope_name"]
|
|
453
234
|
if "asset_code" not in row:
|
|
454
|
-
|
|
235
|
+
try:
|
|
236
|
+
tel.asset_code = names.get_array_element_type_from_name(tel.name)
|
|
237
|
+
# asset code is not a valid telescope name; possibly a calibration device
|
|
238
|
+
except ValueError:
|
|
239
|
+
tel.asset_code = tel.name.split("-")[0]
|
|
455
240
|
except KeyError:
|
|
456
241
|
pass
|
|
457
242
|
try:
|
|
@@ -468,39 +253,13 @@ class ArrayLayout:
|
|
|
468
253
|
if tel.name is None:
|
|
469
254
|
msg = "Missing required row with telescope_name or asset_code/sequence_number"
|
|
470
255
|
self._logger.error(msg)
|
|
471
|
-
raise
|
|
256
|
+
raise InvalidTelescopeListFileError(msg)
|
|
472
257
|
|
|
473
258
|
return tel
|
|
474
259
|
|
|
475
|
-
def _assign_unit_to_quantity(self, value, unit):
|
|
476
|
-
"""
|
|
477
|
-
Assign unit to quantity.
|
|
478
|
-
|
|
479
|
-
Parameters
|
|
480
|
-
----------
|
|
481
|
-
value:
|
|
482
|
-
value to get a unit. It can be a float, int, or a Quantity (convertible to 'unit').
|
|
483
|
-
unit: astropy.units.Unit
|
|
484
|
-
Unit to apply to 'quantity'.
|
|
485
|
-
|
|
486
|
-
Returns
|
|
487
|
-
-------
|
|
488
|
-
astropy.units.Quantity
|
|
489
|
-
Quantity of value 'quantity' and unit 'unit'.
|
|
490
|
-
"""
|
|
491
|
-
if isinstance(value, u.Quantity):
|
|
492
|
-
if isinstance(value.unit, type(unit)):
|
|
493
|
-
return value
|
|
494
|
-
try:
|
|
495
|
-
value = value.to(unit)
|
|
496
|
-
return value
|
|
497
|
-
except u.UnitConversionError:
|
|
498
|
-
self._logger.error(f"Cannot convert {value.unit} to {unit}.")
|
|
499
|
-
raise
|
|
500
|
-
return value * unit
|
|
501
|
-
|
|
502
260
|
def _try_set_coordinate(self, row, tel, table, crs_name, key1, key2):
|
|
503
|
-
"""
|
|
261
|
+
"""
|
|
262
|
+
Try and set coordinates for all coordinate systems.
|
|
504
263
|
|
|
505
264
|
Parameters
|
|
506
265
|
----------
|
|
@@ -520,16 +279,17 @@ class ArrayLayout:
|
|
|
520
279
|
try:
|
|
521
280
|
tel.set_coordinates(
|
|
522
281
|
crs_name,
|
|
523
|
-
|
|
524
|
-
|
|
282
|
+
value_conversion.get_value_as_quantity(row[key1], table[key1].unit),
|
|
283
|
+
value_conversion.get_value_as_quantity(row[key2], table[key2].unit),
|
|
525
284
|
)
|
|
526
285
|
except KeyError:
|
|
527
286
|
pass
|
|
528
287
|
|
|
529
288
|
def _try_set_altitude(self, row, tel, table):
|
|
530
289
|
"""
|
|
531
|
-
|
|
532
|
-
|
|
290
|
+
Try and set altitude.
|
|
291
|
+
|
|
292
|
+
It sets the altitude of the TelescopePosition instance.
|
|
533
293
|
|
|
534
294
|
Parameters
|
|
535
295
|
----------
|
|
@@ -543,70 +303,159 @@ class ArrayLayout:
|
|
|
543
303
|
try:
|
|
544
304
|
tel.set_altitude(
|
|
545
305
|
self._altitude_from_corsika_z(
|
|
546
|
-
pos_z=
|
|
306
|
+
pos_z=value_conversion.get_value_as_quantity(
|
|
547
307
|
row["position_z"], table["position_z"].unit
|
|
548
308
|
),
|
|
549
|
-
|
|
309
|
+
telescope_axis_height=tel.get_axis_height(),
|
|
550
310
|
)
|
|
551
311
|
)
|
|
552
312
|
except KeyError:
|
|
553
313
|
pass
|
|
554
314
|
try:
|
|
555
|
-
tel.set_altitude(
|
|
315
|
+
tel.set_altitude(
|
|
316
|
+
value_conversion.get_value_as_quantity(row["altitude"], table["altitude"].unit)
|
|
317
|
+
)
|
|
556
318
|
except KeyError:
|
|
557
319
|
pass
|
|
558
320
|
|
|
559
|
-
def
|
|
321
|
+
def _initialize_array_layout(
|
|
322
|
+
self, telescope_list_file, telescope_list_metadata_file=None, validate=False
|
|
323
|
+
):
|
|
560
324
|
"""
|
|
561
|
-
|
|
325
|
+
Initialize the Layout array including site and telescope parameters.
|
|
326
|
+
|
|
327
|
+
Read array list if telescope_list_file is given.
|
|
562
328
|
|
|
563
329
|
Parameters
|
|
564
330
|
----------
|
|
565
|
-
|
|
566
|
-
|
|
331
|
+
telescope_list_file: str or Path
|
|
332
|
+
Path to the telescope list file.
|
|
333
|
+
telescope_list_metadata_file: str or Path
|
|
334
|
+
Path to the telescope list metadata file.
|
|
335
|
+
validate: bool
|
|
336
|
+
Validate telescope list file against schema.
|
|
567
337
|
|
|
338
|
+
Returns
|
|
339
|
+
-------
|
|
340
|
+
astropy.table.QTable
|
|
341
|
+
Table with the telescope layout information.
|
|
568
342
|
"""
|
|
343
|
+
self._logger.debug("Initializing array (site and telescope parameters)")
|
|
344
|
+
self._initialize_site_parameters_from_db()
|
|
345
|
+
self._initialize_coordinate_systems()
|
|
346
|
+
|
|
347
|
+
if telescope_list_file is None:
|
|
348
|
+
return None
|
|
349
|
+
|
|
350
|
+
self._logger.debug(f"Reading telescope list from {telescope_list_file}")
|
|
351
|
+
if Path(telescope_list_file).suffix == ".json":
|
|
352
|
+
table = self._read_table_from_json_file(file_name=telescope_list_file)
|
|
353
|
+
else:
|
|
354
|
+
table = data_reader.read_table_from_file(
|
|
355
|
+
file_name=telescope_list_file,
|
|
356
|
+
validate=validate,
|
|
357
|
+
metadata_file=telescope_list_metadata_file,
|
|
358
|
+
)
|
|
359
|
+
|
|
569
360
|
for row in table:
|
|
570
361
|
tel = self._load_telescope_names(row)
|
|
362
|
+
if names.get_collection_name_from_array_element_name(tel.name) == "telescopes":
|
|
363
|
+
self._set_telescope_auxiliary_parameters(tel)
|
|
571
364
|
self._try_set_coordinate(row, tel, table, "ground", "position_x", "position_y")
|
|
572
365
|
self._try_set_coordinate(row, tel, table, "utm", "utm_east", "utm_north")
|
|
573
366
|
self._try_set_coordinate(row, tel, table, "mercator", "latitude", "longitude")
|
|
574
367
|
self._try_set_altitude(row, tel, table)
|
|
575
|
-
|
|
576
368
|
self._telescope_list.append(tel)
|
|
577
369
|
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
):
|
|
370
|
+
return table
|
|
371
|
+
|
|
372
|
+
def _read_table_from_json_file(self, file_name):
|
|
581
373
|
"""
|
|
582
|
-
|
|
374
|
+
Read a telescope position from a json file and return as astropy table.
|
|
583
375
|
|
|
584
376
|
Parameters
|
|
585
377
|
----------
|
|
586
|
-
|
|
587
|
-
Path to the
|
|
588
|
-
telescope_list_metadata_file: str or Path
|
|
589
|
-
Path to the telescope list metadata file.
|
|
590
|
-
validate: bool
|
|
591
|
-
Validate the telescope list file.
|
|
378
|
+
file_name: str or Path
|
|
379
|
+
Path to the json file.
|
|
592
380
|
|
|
593
381
|
Returns
|
|
594
382
|
-------
|
|
595
383
|
astropy.table.QTable
|
|
596
384
|
Table with the telescope layout information.
|
|
597
385
|
"""
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
validate=validate,
|
|
601
|
-
metadata_file=telescope_list_metadata_file,
|
|
602
|
-
)
|
|
603
|
-
self._initialize_corsika_telescope(table.meta)
|
|
604
|
-
self._initialize_coordinate_systems(table.meta)
|
|
605
|
-
self._load_telescope_list(table)
|
|
386
|
+
with Path(file_name).open("r", encoding="utf-8") as file:
|
|
387
|
+
data = json.load(file)
|
|
606
388
|
|
|
389
|
+
position = gen.convert_string_to_list(data["value"])
|
|
390
|
+
self.site = data.get("site", None)
|
|
391
|
+
|
|
392
|
+
table = QTable()
|
|
393
|
+
table["telescope_name"] = [data["instrument"]]
|
|
394
|
+
if "utm" in data["parameter"]:
|
|
395
|
+
table["utm_east"] = [position[0]] * u.Unit(data["unit"])
|
|
396
|
+
table["utm_north"] = [position[1]] * u.Unit(data["unit"])
|
|
397
|
+
table["altitude"] = [position[2]] * u.Unit(data["unit"])
|
|
398
|
+
else:
|
|
399
|
+
table["position_x"] = [position[0]] * u.Unit(data["unit"])
|
|
400
|
+
table["position_y"] = [position[1]] * u.Unit(data["unit"])
|
|
401
|
+
table["position_z"] = [position[2]] * u.Unit(data["unit"])
|
|
607
402
|
return table
|
|
608
403
|
|
|
609
|
-
def
|
|
404
|
+
def _get_telescope_model(self, telescope_name):
|
|
405
|
+
"""
|
|
406
|
+
Get telescope model from the database.
|
|
407
|
+
|
|
408
|
+
Parameters
|
|
409
|
+
----------
|
|
410
|
+
telescope_name: str
|
|
411
|
+
Name of the telescope.
|
|
412
|
+
|
|
413
|
+
Returns
|
|
414
|
+
-------
|
|
415
|
+
TelescopeModel
|
|
416
|
+
Telescope model instance.
|
|
417
|
+
"""
|
|
418
|
+
return TelescopeModel(
|
|
419
|
+
site=self.site,
|
|
420
|
+
telescope_name=telescope_name,
|
|
421
|
+
model_version=self.model_version,
|
|
422
|
+
mongo_db_config=self.mongo_db_config,
|
|
423
|
+
label=self.label,
|
|
424
|
+
)
|
|
425
|
+
|
|
426
|
+
def _set_telescope_auxiliary_parameters(self, telescope, telescope_name=None):
|
|
427
|
+
"""
|
|
428
|
+
Set auxiliary CORSIKA parameters for a telescope.
|
|
429
|
+
|
|
430
|
+
Uses as default the design model if telescope is not found in the database.
|
|
431
|
+
|
|
432
|
+
Parameters
|
|
433
|
+
----------
|
|
434
|
+
telescope: TelescopePosition
|
|
435
|
+
Instance of TelescopePosition.
|
|
436
|
+
|
|
437
|
+
"""
|
|
438
|
+
telescope_name = telescope_name if telescope_name is not None else telescope.name
|
|
439
|
+
if names.get_collection_name_from_array_element_name(telescope_name) == "telescopes":
|
|
440
|
+
self._logger.debug(
|
|
441
|
+
f"Reading auxiliary telescope parameters for {telescope_name}"
|
|
442
|
+
f" (model version {self.model_version})"
|
|
443
|
+
)
|
|
444
|
+
try:
|
|
445
|
+
tel_model = self._get_telescope_model(telescope_name)
|
|
446
|
+
except ValueError:
|
|
447
|
+
tel_model = self._get_telescope_model(
|
|
448
|
+
names.get_array_element_type_from_name(telescope_name) + "-design",
|
|
449
|
+
)
|
|
450
|
+
|
|
451
|
+
for para in ("telescope_axis_height", "telescope_sphere_radius"):
|
|
452
|
+
telescope.set_auxiliary_parameter(
|
|
453
|
+
para, tel_model.get_parameter_value_with_unit(para)
|
|
454
|
+
)
|
|
455
|
+
|
|
456
|
+
def add_telescope(
|
|
457
|
+
self, telescope_name, crs_name, xx, yy, altitude=None, tel_corsika_z=None, design_model=None
|
|
458
|
+
):
|
|
610
459
|
"""
|
|
611
460
|
Add an individual telescope to the telescope list.
|
|
612
461
|
|
|
@@ -625,25 +474,28 @@ class ArrayLayout:
|
|
|
625
474
|
tel_corsika_z: astropy.units.quantity.Quantity
|
|
626
475
|
CORSIKA z-position (requires setting of CORSIKA observation level and telescope sphere\
|
|
627
476
|
center).
|
|
477
|
+
design_model: str
|
|
478
|
+
Name of the design model (optional).
|
|
479
|
+
If none, telescope type + "-design" is used.
|
|
628
480
|
"""
|
|
629
|
-
|
|
630
481
|
tel = TelescopePosition(name=telescope_name)
|
|
482
|
+
self._set_telescope_auxiliary_parameters(tel, design_model)
|
|
631
483
|
tel.set_coordinates(crs_name, xx, yy)
|
|
632
484
|
if altitude is not None:
|
|
633
485
|
tel.set_altitude(altitude)
|
|
634
486
|
elif tel_corsika_z is not None:
|
|
635
|
-
tel.set_altitude(
|
|
487
|
+
tel.set_altitude(
|
|
488
|
+
self._altitude_from_corsika_z(
|
|
489
|
+
pos_z=tel_corsika_z, telescope_axis_height=tel.get_axis_height()
|
|
490
|
+
)
|
|
491
|
+
)
|
|
636
492
|
self._telescope_list.append(tel)
|
|
637
493
|
|
|
638
|
-
def _get_export_metadata(self
|
|
494
|
+
def _get_export_metadata(self):
|
|
639
495
|
"""
|
|
640
|
-
File metadata for export of array element list to file.
|
|
641
|
-
CORSIKA telescope parameters, and EPSG center
|
|
496
|
+
File metadata for export of array element list to file.
|
|
642
497
|
|
|
643
|
-
|
|
644
|
-
----------
|
|
645
|
-
export_corsika_meta: bool
|
|
646
|
-
write CORSIKA metadata.
|
|
498
|
+
Included array center definition, CORSIKA telescope parameters, and EPSG code.
|
|
647
499
|
|
|
648
500
|
Returns
|
|
649
501
|
-------
|
|
@@ -651,31 +503,19 @@ class ArrayLayout:
|
|
|
651
503
|
Metadata header for array element list export.
|
|
652
504
|
|
|
653
505
|
"""
|
|
654
|
-
|
|
655
|
-
_meta = {
|
|
656
|
-
"center_lon": None,
|
|
657
|
-
"center_lat": None,
|
|
658
|
-
"center_northing": None,
|
|
659
|
-
"center_easting": None,
|
|
660
|
-
"center_alt": None,
|
|
661
|
-
}
|
|
506
|
+
_meta = {}
|
|
662
507
|
if self._array_center:
|
|
663
|
-
_meta["center_lat"], _meta["center_lon"], _ = self._array_center.get_coordinates(
|
|
664
|
-
"mercator"
|
|
665
|
-
)
|
|
666
508
|
(
|
|
667
509
|
_meta["center_easting"],
|
|
668
510
|
_meta["center_northing"],
|
|
669
|
-
_meta["
|
|
511
|
+
_meta["center_altitude"],
|
|
670
512
|
) = self._array_center.get_coordinates("utm")
|
|
671
|
-
|
|
672
|
-
_meta.update(self._corsika_telescope)
|
|
673
|
-
_meta["EPSG"] = self._epsg
|
|
513
|
+
_meta["epsg_code"] = self._reference_position_dict.get("epsg_code", None)
|
|
674
514
|
_meta["array_name"] = self.name
|
|
675
515
|
|
|
676
516
|
return _meta
|
|
677
517
|
|
|
678
|
-
def export_telescope_list_table(self, crs_name
|
|
518
|
+
def export_telescope_list_table(self, crs_name):
|
|
679
519
|
"""
|
|
680
520
|
Export array elements positions to astropy table.
|
|
681
521
|
|
|
@@ -683,31 +523,31 @@ class ArrayLayout:
|
|
|
683
523
|
----------
|
|
684
524
|
crs_name: str
|
|
685
525
|
Name of coordinate system to be used for export.
|
|
686
|
-
corsika_z: bool
|
|
687
|
-
Write telescope height in CORSIKA coordinates (for CORSIKA system).
|
|
688
526
|
|
|
689
527
|
Returns
|
|
690
528
|
-------
|
|
691
529
|
astropy.table.QTable
|
|
692
530
|
Astropy table with the telescope layout information.
|
|
693
|
-
|
|
694
531
|
"""
|
|
695
|
-
|
|
696
|
-
table = QTable(meta=self._get_export_metadata(crs_name == "ground"))
|
|
532
|
+
table = QTable(meta=self._get_export_metadata())
|
|
697
533
|
|
|
698
534
|
tel_names, asset_code, sequence_number, geo_code = [], [], [], []
|
|
699
|
-
pos_x, pos_y, pos_z = [], [], []
|
|
535
|
+
pos_x, pos_y, pos_z, pos_t, tel_r = [], [], [], [], []
|
|
700
536
|
for tel in self._telescope_list:
|
|
701
537
|
tel_names.append(tel.name)
|
|
702
538
|
asset_code.append(tel.asset_code)
|
|
703
539
|
sequence_number.append(tel.sequence_number)
|
|
704
540
|
geo_code.append(tel.geo_code)
|
|
705
541
|
x, y, z = tel.get_coordinates(crs_name)
|
|
706
|
-
if
|
|
707
|
-
z = self._altitude_from_corsika_z(
|
|
542
|
+
if crs_name == "ground":
|
|
543
|
+
z = self._altitude_from_corsika_z(
|
|
544
|
+
altitude=z, telescope_axis_height=tel.get_axis_height()
|
|
545
|
+
)
|
|
546
|
+
pos_t.append(tel.get_axis_height())
|
|
708
547
|
pos_x.append(x)
|
|
709
548
|
pos_y.append(y)
|
|
710
549
|
pos_z.append(z)
|
|
550
|
+
tel_r.append(tel.get_sphere_radius())
|
|
711
551
|
|
|
712
552
|
# prefer asset_code / sequence_number of telescope_name
|
|
713
553
|
if all(v is not None for v in asset_code) and all(v is not None for v in sequence_number):
|
|
@@ -724,137 +564,115 @@ class ArrayLayout:
|
|
|
724
564
|
)
|
|
725
565
|
table[_name_x] = pos_x
|
|
726
566
|
table[_name_y] = pos_y
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
567
|
+
table[_name_z] = pos_z
|
|
568
|
+
if len(pos_t) > 0:
|
|
569
|
+
table["telescope_axis_height"] = pos_t
|
|
570
|
+
if len(tel_r) > 0:
|
|
571
|
+
table["sphere_radius"] = tel_r
|
|
731
572
|
except IndexError:
|
|
732
573
|
pass
|
|
733
574
|
|
|
575
|
+
if "telescope_name" in table.colnames:
|
|
576
|
+
table.sort("telescope_name")
|
|
577
|
+
if "asset_code" in table.colnames:
|
|
578
|
+
table.sort(["asset_code", "sequence_number"])
|
|
579
|
+
|
|
734
580
|
return table
|
|
735
581
|
|
|
736
|
-
def
|
|
582
|
+
def export_one_telescope_as_json(self, crs_name):
|
|
737
583
|
"""
|
|
738
|
-
Return
|
|
584
|
+
Return a list containing a single telescope in simtools-DB-style json.
|
|
585
|
+
|
|
586
|
+
Parameters
|
|
587
|
+
----------
|
|
588
|
+
crs_name: str
|
|
589
|
+
Name of coordinate system to be used for export.
|
|
739
590
|
|
|
740
591
|
Returns
|
|
741
592
|
-------
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
"""
|
|
745
|
-
|
|
593
|
+
dict
|
|
594
|
+
Dictionary with array element information.
|
|
595
|
+
"""
|
|
596
|
+
table = self.export_telescope_list_table(crs_name)
|
|
597
|
+
if len(table) != 1:
|
|
598
|
+
raise ValueError("Only one telescope can be exported to json")
|
|
599
|
+
parameter_name = value_string = None
|
|
600
|
+
if crs_name == "ground":
|
|
601
|
+
parameter_name = "array_element_position_ground"
|
|
602
|
+
value_string = gen.convert_list_to_string(
|
|
603
|
+
[
|
|
604
|
+
table["position_x"][0].value,
|
|
605
|
+
table["position_y"][0].value,
|
|
606
|
+
table["position_z"][0].value,
|
|
607
|
+
]
|
|
608
|
+
)
|
|
609
|
+
elif crs_name == "utm":
|
|
610
|
+
parameter_name = "array_element_position_utm"
|
|
611
|
+
value_string = gen.convert_list_to_string(
|
|
612
|
+
[
|
|
613
|
+
table["utm_east"][0].value,
|
|
614
|
+
table["utm_north"][0].value,
|
|
615
|
+
table["altitude"][0].value,
|
|
616
|
+
]
|
|
617
|
+
)
|
|
618
|
+
elif crs_name == "mercator":
|
|
619
|
+
parameter_name = "array_element_position_mercator"
|
|
620
|
+
value_string = gen.convert_list_to_string(
|
|
621
|
+
[
|
|
622
|
+
table["latitude"][0].value,
|
|
623
|
+
table["longitude"][0].value,
|
|
624
|
+
table["altitude"][0].value,
|
|
625
|
+
]
|
|
626
|
+
)
|
|
627
|
+
return {
|
|
628
|
+
"parameter": parameter_name,
|
|
629
|
+
"instrument": table["telescope_name"][0],
|
|
630
|
+
"site": self.site,
|
|
631
|
+
"version": self.model_version,
|
|
632
|
+
"value": value_string,
|
|
633
|
+
"unit": "m",
|
|
634
|
+
"type": "float64",
|
|
635
|
+
"applicable": True,
|
|
636
|
+
"file": False,
|
|
637
|
+
}
|
|
746
638
|
|
|
747
|
-
def
|
|
639
|
+
def get_number_of_telescopes(self):
|
|
748
640
|
"""
|
|
749
|
-
|
|
641
|
+
Return the number of telescopes in the list.
|
|
750
642
|
|
|
751
643
|
Returns
|
|
752
644
|
-------
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
Raises
|
|
757
|
-
------
|
|
758
|
-
KeyError
|
|
759
|
-
if Missing definition of CORSIKA sphere radius or obs_level.
|
|
760
|
-
"""
|
|
761
|
-
|
|
762
|
-
corsika_list = ""
|
|
763
|
-
for tel in self._telescope_list:
|
|
764
|
-
pos_x, pos_y, pos_z = tel.get_coordinates("ground")
|
|
765
|
-
try:
|
|
766
|
-
sphere_radius = self._corsika_telescope["corsika_sphere_radius"][
|
|
767
|
-
names.get_telescope_type(tel.name)
|
|
768
|
-
]
|
|
769
|
-
except KeyError:
|
|
770
|
-
self._logger.error("Missing definition of CORSIKA sphere radius")
|
|
771
|
-
raise
|
|
772
|
-
try:
|
|
773
|
-
pos_z = tel.convert_telescope_altitude_to_corsika_system(
|
|
774
|
-
pos_z,
|
|
775
|
-
self._corsika_telescope["corsika_obs_level"],
|
|
776
|
-
self._get_corsika_sphere_center(tel.name),
|
|
777
|
-
)
|
|
778
|
-
except KeyError:
|
|
779
|
-
self._logger.error("Missing definition of CORSIKA sphere center / obs_level")
|
|
780
|
-
raise
|
|
781
|
-
|
|
782
|
-
corsika_list += "TELESCOPE"
|
|
783
|
-
for pos in [pos_x, pos_y, pos_z]:
|
|
784
|
-
corsika_list += f"\t {pos.value:.3f}E2"
|
|
785
|
-
corsika_list += f"\t {sphere_radius.value:.3f}E2"
|
|
786
|
-
corsika_list += f"\t # {tel.name}\n"
|
|
787
|
-
|
|
788
|
-
return corsika_list
|
|
789
|
-
|
|
790
|
-
def _print_all(self):
|
|
791
|
-
""" "
|
|
792
|
-
Print all columns for all coordinate systems.
|
|
793
|
-
|
|
645
|
+
int
|
|
646
|
+
Number of telescopes.
|
|
794
647
|
"""
|
|
648
|
+
return len(self._telescope_list)
|
|
795
649
|
|
|
796
|
-
|
|
797
|
-
print("ArrayCenter")
|
|
798
|
-
print(self._array_center)
|
|
799
|
-
print("Telescopes")
|
|
800
|
-
for tel in self._telescope_list:
|
|
801
|
-
print(tel)
|
|
802
|
-
|
|
803
|
-
def _print_compact(self, compact_printing, corsika_z=False):
|
|
650
|
+
def print_telescope_list(self, crs_name):
|
|
804
651
|
"""
|
|
805
|
-
|
|
806
|
-
|
|
652
|
+
Print list of telescopes.
|
|
807
653
|
|
|
808
654
|
Parameters
|
|
809
655
|
----------
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
printed, if compact_printing is None.
|
|
813
|
-
corsika_z: bool
|
|
814
|
-
Print telescope height in CORSIKA coordinates (for CORSIKA system)
|
|
656
|
+
crs_name: str
|
|
657
|
+
Name of coordinate system to be used for export.
|
|
815
658
|
|
|
816
659
|
"""
|
|
817
|
-
|
|
818
660
|
for tel in self._telescope_list:
|
|
819
|
-
if corsika_z:
|
|
820
|
-
_corsika_obs_level = self._corsika_telescope["corsika_obs_level"]
|
|
821
|
-
_corsika_sphere_center = self._get_corsika_sphere_center(tel.name)
|
|
822
|
-
else:
|
|
823
|
-
_corsika_obs_level = None
|
|
824
|
-
_corsika_sphere_center = None
|
|
825
|
-
|
|
826
661
|
tel.print_compact_format(
|
|
827
|
-
crs_name=
|
|
662
|
+
crs_name=crs_name,
|
|
828
663
|
print_header=(tel == self._telescope_list[0]),
|
|
829
|
-
|
|
830
|
-
|
|
664
|
+
corsika_observation_level=(
|
|
665
|
+
self._corsika_observation_level if crs_name == "ground" else None
|
|
666
|
+
),
|
|
831
667
|
)
|
|
832
668
|
|
|
833
|
-
def print_telescope_list(self, compact_printing="", corsika_z=False):
|
|
834
|
-
"""
|
|
835
|
-
Print list of telescopes in latest released layout.
|
|
836
|
-
|
|
837
|
-
Parameters
|
|
838
|
-
----------
|
|
839
|
-
compact_printing: str
|
|
840
|
-
Compact printout for a single coordinate system.
|
|
841
|
-
corsika_z: bool
|
|
842
|
-
Print telescope height in CORSIKA coordinates (for CORSIKA system).
|
|
843
|
-
"""
|
|
844
|
-
|
|
845
|
-
if len(compact_printing) == 0:
|
|
846
|
-
self._print_all()
|
|
847
|
-
else:
|
|
848
|
-
self._print_compact(compact_printing, corsika_z)
|
|
849
|
-
|
|
850
669
|
def convert_coordinates(self):
|
|
851
670
|
"""Perform all the possible conversions the coordinates of the tel positions."""
|
|
852
|
-
|
|
853
671
|
self._logger.info("Converting telescope coordinates")
|
|
854
672
|
|
|
855
673
|
crs_wgs84 = self.geo_coordinates.crs_wgs84()
|
|
856
674
|
crs_local = self.geo_coordinates.crs_local(self._array_center)
|
|
857
|
-
crs_utm = self.geo_coordinates.crs_utm(self.
|
|
675
|
+
crs_utm = self.geo_coordinates.crs_utm(self._reference_position_dict.get("epsg_code", None))
|
|
858
676
|
|
|
859
677
|
for tel in self._telescope_list:
|
|
860
678
|
tel.convert_all(
|
|
@@ -863,35 +681,6 @@ class ArrayLayout:
|
|
|
863
681
|
crs_utm=crs_utm,
|
|
864
682
|
)
|
|
865
683
|
|
|
866
|
-
@staticmethod
|
|
867
|
-
def include_radius_into_telescope_table(telescope_table):
|
|
868
|
-
"""
|
|
869
|
-
Include the radius of the telescopes types into the astropy.table.QTable telescopes_table
|
|
870
|
-
|
|
871
|
-
Parameters
|
|
872
|
-
----------
|
|
873
|
-
telescope_table: astropy.QTable
|
|
874
|
-
Astropy QTable with telescope information.
|
|
875
|
-
|
|
876
|
-
Returns
|
|
877
|
-
-------
|
|
878
|
-
astropy.QTable
|
|
879
|
-
Astropy QTable with telescope information updated with the radius.
|
|
880
|
-
"""
|
|
881
|
-
|
|
882
|
-
telescope_table["radius"] = [
|
|
883
|
-
u.Quantity(
|
|
884
|
-
telescope_table.meta["corsika_sphere_radius"][
|
|
885
|
-
names.get_telescope_type(tel_name_now)
|
|
886
|
-
]
|
|
887
|
-
)
|
|
888
|
-
.to("m")
|
|
889
|
-
.value
|
|
890
|
-
for tel_name_now in telescope_table["telescope_name"]
|
|
891
|
-
]
|
|
892
|
-
telescope_table["radius"] = telescope_table["radius"].quantity * u.m
|
|
893
|
-
return telescope_table
|
|
894
|
-
|
|
895
684
|
def select_assets(self, asset_list=None):
|
|
896
685
|
"""
|
|
897
686
|
Select a subsets of telescopes / assets from the layout.
|
|
@@ -899,7 +688,7 @@ class ArrayLayout:
|
|
|
899
688
|
Parameters
|
|
900
689
|
----------
|
|
901
690
|
asset_list: list
|
|
902
|
-
List of assets to be selected
|
|
691
|
+
List of assets to be selected (telescope names or types)
|
|
903
692
|
|
|
904
693
|
Raises
|
|
905
694
|
------
|
|
@@ -907,13 +696,20 @@ class ArrayLayout:
|
|
|
907
696
|
If the asset list is empty.
|
|
908
697
|
|
|
909
698
|
"""
|
|
910
|
-
|
|
911
699
|
_n_telescopes = len(self._telescope_list)
|
|
912
700
|
try:
|
|
913
701
|
if len(asset_list) > 0:
|
|
914
|
-
|
|
702
|
+
_telescope_list_from_name = [
|
|
915
703
|
tel for tel in self._telescope_list if tel.asset_code in asset_list
|
|
916
704
|
]
|
|
705
|
+
_telescope_list_from_type = [
|
|
706
|
+
tel
|
|
707
|
+
for tel in self._telescope_list
|
|
708
|
+
if names.get_array_element_type_from_name(tel.asset_code) in asset_list
|
|
709
|
+
]
|
|
710
|
+
self._telescope_list = list(
|
|
711
|
+
set(_telescope_list_from_name + _telescope_list_from_type)
|
|
712
|
+
)
|
|
917
713
|
self._logger.info(
|
|
918
714
|
f"Selected {len(self._telescope_list)} telescopes"
|
|
919
715
|
f" (from originally {_n_telescopes})"
|