-
Notifications
You must be signed in to change notification settings - Fork 9
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #154 from cta-observatory/Torino
MCP upgrades: semi-automatic scripts and update of the current scripts (1 LST -> 4 LSTs); Torino team
- Loading branch information
Showing
27 changed files
with
1,510 additions
and
352 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,140 @@ | ||
import numpy as np | ||
from ctapipe.image import ( | ||
apply_time_delta_cleaning, | ||
number_of_islands, | ||
tailcuts_clean, | ||
) | ||
from ctapipe.instrument import CameraGeometry | ||
from lstchain.image.cleaning import apply_dynamic_cleaning | ||
from lstchain.image.modifier import ( | ||
add_noise_in_pixels, | ||
random_psf_smearer, | ||
set_numba_seed | ||
) | ||
from magicctapipe.image import MAGICClean | ||
|
||
|
||
__all__ = [ | ||
"calibrate" | ||
] | ||
|
||
|
||
def calibrate(event, tel_id, config, calibrator, is_lst, obs_id=None, camera_geoms=None, magic_clean=None): | ||
|
||
""" | ||
This function calibrates the camera image for a single event of a telescope | ||
Parameters | ||
---------- | ||
event: event | ||
From an EventSource | ||
tel_id: int | ||
Telescope ID | ||
config: dictionary | ||
Parameters for image extraction and calibration | ||
calibrator: CameraCalibrator (ctapipe.calib) | ||
ctapipe object needed to calibrate the camera | ||
is_lst: bool | ||
Whether the telescope is a LST | ||
obs_id: int | ||
Observation ID. Unsed in case of LST telescope | ||
camera_geoms: telescope.camera.geometry | ||
Camera geometry. Used in case of LST telescope | ||
magic_clean: dictionary (1 entry per MAGIC telescope) | ||
Each entry is a MAGICClean object using the telescope camera geometry. Used in case of MAGIC telescope | ||
Returns | ||
------- | ||
signal_pixels: boolean mask | ||
Mask of the pixels selected by the cleaning | ||
image: numpy array | ||
Array of number of p.e. in the camera pixels | ||
peak_time: numpy array | ||
Array of the signal peak time in the camera pixels | ||
""" | ||
if (not is_lst) and (magic_clean==None): | ||
raise ValueError("Check the provided parameters and the telescope type; MAGIC calibration not possible if magic_clean not provided") | ||
if (is_lst) and (obs_id==None): | ||
raise ValueError("Check the provided parameters and the telescope type; LST calibration not possible if obs_id not provided") | ||
if (is_lst) and (camera_geoms==None): | ||
raise ValueError("Check the provided parameters and the telescope type; LST calibration not possible if gamera_geoms not provided") | ||
if (not is_lst) and (type(magic_clean[tel_id])!=MAGICClean): | ||
raise ValueError("Check the provided magic_clean parameter; MAGIC calibration not possible if magic_clean not a dictionary of MAGICClean objects") | ||
if (is_lst) and (type(camera_geoms[tel_id])!=CameraGeometry): | ||
raise ValueError("Check the provided camera_geoms parameter; LST calibration not possible if camera_geoms not a dictionary of CameraGeometry objects") | ||
|
||
calibrator._calibrate_dl0(event, tel_id) | ||
calibrator._calibrate_dl1(event, tel_id) | ||
|
||
image = event.dl1.tel[tel_id].image.astype(np.float64) | ||
peak_time = event.dl1.tel[tel_id].peak_time.astype(np.float64) | ||
|
||
if not is_lst: | ||
use_charge_correction = config["charge_correction"]["use"] | ||
|
||
if use_charge_correction: | ||
# Scale the charges by the correction factor | ||
image *= config["charge_correction"]["factor"] | ||
|
||
# Apply the image cleaning | ||
signal_pixels, image, peak_time = magic_clean[tel_id].clean_image( | ||
event_image=image, event_pulse_time=peak_time | ||
) | ||
|
||
else: | ||
increase_nsb = config["increase_nsb"].pop("use") | ||
increase_psf = config["increase_psf"]["use"] | ||
use_time_delta_cleaning = config["time_delta_cleaning"].pop("use") | ||
use_dynamic_cleaning = config["dynamic_cleaning"].pop("use") | ||
use_only_main_island = config["use_only_main_island"] | ||
|
||
if increase_nsb: | ||
rng = np.random.default_rng(obs_id) | ||
# Add extra noise in pixels | ||
image = add_noise_in_pixels(rng, image, **config["increase_nsb"]) | ||
|
||
if increase_psf: | ||
set_numba_seed(obs_id) | ||
# Smear the image | ||
image = random_psf_smearer( | ||
image=image, | ||
fraction=config["increase_psf"]["fraction"], | ||
indices=camera_geoms[tel_id].neighbor_matrix_sparse.indices, | ||
indptr=camera_geoms[tel_id].neighbor_matrix_sparse.indptr, | ||
) | ||
|
||
# Apply the image cleaning | ||
signal_pixels = tailcuts_clean( | ||
camera_geoms[tel_id], image, **config["tailcuts_clean"] | ||
) | ||
|
||
if use_time_delta_cleaning: | ||
signal_pixels = apply_time_delta_cleaning( | ||
geom=camera_geoms[tel_id], | ||
mask=signal_pixels, | ||
arrival_times=peak_time, | ||
**config["time_delta_cleaning"], | ||
) | ||
|
||
if use_dynamic_cleaning: | ||
signal_pixels = apply_dynamic_cleaning( | ||
image, signal_pixels, **config["dynamic_cleaning"] | ||
) | ||
|
||
if use_only_main_island: | ||
_, island_labels = number_of_islands(camera_geoms[tel_id], signal_pixels) | ||
n_pixels_on_island = np.bincount(island_labels.astype(np.int64)) | ||
|
||
# The first index means the pixels not surviving | ||
# the cleaning, so should not be considered | ||
n_pixels_on_island[0] = 0 | ||
max_island_label = np.argmax(n_pixels_on_island) | ||
signal_pixels[island_labels != max_island_label] = False | ||
|
||
config["increase_nsb"]["use"]=increase_nsb | ||
config["time_delta_cleaning"]["use"]=use_time_delta_cleaning | ||
config["dynamic_cleaning"]["use"]=use_dynamic_cleaning | ||
|
||
return signal_pixels, image, peak_time |
Oops, something went wrong.