diff --git a/src/ctapipe/image/cleaning.py b/src/ctapipe/image/cleaning.py index d2dbd38dc71..78afed826c4 100644 --- a/src/ctapipe/image/cleaning.py +++ b/src/ctapipe/image/cleaning.py @@ -28,8 +28,7 @@ import numpy as np -from ctapipe.containers import MonitoringCameraContainer - +from ..containers import MonitoringCameraContainer from ..core import TelescopeComponent from ..core.traits import ( BoolTelescopeParameter, @@ -503,29 +502,24 @@ def lst_image_cleaning( boundary_thresh=4, min_number_picture_neighbors=2, keep_isolated_pixels=False, - apply_time_cleaning=True, time_limit=2, time_num_neighbors=1, - apply_bright_cleaning=True, bright_cleaning_fraction=0.03, bright_cleaning_threshold=267, largest_island_only=False, - apply_pedestal_cleaning=True, pedestal_factor=2.5, pedestal_std=None, ): """ Clean an image in 5 Steps: - 1) Get picture threshold for `tailcuts_clean` in step 2) from interleaved - pedestal events if `apply_pedestal_cleaning` is set to true - and `pedestal_std` is not None. + 1) Get picture thresholds for `tailcuts_clean` in step 2) from interleaved + pedestal events `pedestal_std` is not None. 2) Apply tailcuts image cleaning algorithm - `ctapipe.image.cleaning.tailcuts_clean`. 3) Apply time_delta_cleaning algorithm - - `ctapipe.image.cleaning.apply_time_delta_cleaning` if `apply_time_cleaning` is - set to true. + `ctapipe.image.cleaning.apply_time_delta_cleaning` if time_limit is not None. 4) Apply bright_cleaning - `ctapipe.image.cleaning.bright_cleaning` if - `apply_bright_cleaning` is set to true. + bright_cleaning_threshold is not None. 5) Get only largest island - `ctapipe.image.morphology.largest_island` if `largest_island_only` is set to true. @@ -550,27 +544,24 @@ def lst_image_cleaning( If True, pixels above the picture threshold will be included always, if not they are only included if a neighbor is in the picture or boundary. Used for `tailcuts_clean`. - apply_time_cleaning: `bool` - Set to true if `time_delta_cleaning` should be applied. time_limit: `float` - Time limit for the `time_delta_cleaning`. + Time limit for the `time_delta_cleaning`. Set to None if no `time_delta_cleaning` + should be applied. time_num_neighbors: int Used for `time_delta_cleaning`. A selected pixel needs at least this number of (already selected) neighbors that arrived within a given time_limit to itself to survive this cleaning. - apply_bright_cleaning: `bool` - Set to true if `bright_cleaning` should be applied. bright_cleaning_fraction: `float` `fraction` parameter for `bright_cleaning`. Pixels below fraction * (average charge in the 3 brightest pixels) will be removed from - the cleaned image. + the cleaned image. Set `bright_cleaning_threshold` to None if no + `bright_cleaning` should be applied. bright_cleaning_threshold: `float` `threshold` parameter for `bright_cleaning`. Minimum average charge - in the 3 brightest pixels to apply the cleaning. + in the 3 brightest pixels to apply the cleaning. Set to None if no + `bright_cleaning` should be applied. largest_island_only: `bool` Set to true to get only largest island. - apply_pedestal_cleaning: `bool` - Set to true if pedestal cleaning should be applied. pedestal_factor: `float` Factor for interleaved pedestal cleaning. It is multiplied by the pedestal standard deviation for each pixel to calculate pixelwise picture @@ -585,7 +576,7 @@ def lst_image_cleaning( """ # Step 1 - if apply_pedestal_cleaning and pedestal_std is not None: + if pedestal_std is not None: pedestal_threshold = pedestal_std * pedestal_factor picture_thresh = np.clip(pedestal_threshold, picture_thresh, None) @@ -603,7 +594,7 @@ def lst_image_cleaning( return mask # Step 3 - if apply_time_cleaning: + if time_limit is not None: mask = apply_time_delta_cleaning( geom, mask, @@ -613,7 +604,7 @@ def lst_image_cleaning( ) # Step 4 - if apply_bright_cleaning: + if bright_cleaning_threshold is not None: mask &= bright_cleaning( image, bright_cleaning_threshold, bright_cleaning_fraction ) @@ -717,14 +708,11 @@ class LSTImageCleaner(TailcutsImageCleaner): `ctapipe.image.lst_image_cleaning` """ - apply_time_cleaning = BoolTelescopeParameter( - default_value=True, - help="Set to true if `time_delta_cleaning` should be applied", - ).tag(config=True) - time_limit = FloatTelescopeParameter( default_value=2, - help="Time limit for the `time_delta_cleaning`.", + help="Time limit for the `time_delta_cleaning`. Set to None if no" + " `time_delta_cleaning` should be applied.", + allow_none=True, ).tag(config=True) time_num_neighbors = IntTelescopeParameter( @@ -734,10 +722,6 @@ class LSTImageCleaner(TailcutsImageCleaner): " that arrived within a given time_limit to itself to survive this cleaning.", ).tag(config=True) - apply_bright_cleaning = BoolTelescopeParameter( - default_value=True, help="Set to true if `bright_cleaning` should be applied" - ).tag(config=True) - bright_cleaning_fraction = FloatTelescopeParameter( default_value=0.03, help="`fraction` parameter for `bright_cleaning`. Pixels below" @@ -748,17 +732,15 @@ class LSTImageCleaner(TailcutsImageCleaner): bright_cleaning_threshold = FloatTelescopeParameter( default_value=267, help="`threshold` parameter for `bright_cleaning`. Minimum average charge" - " in the 3 brightest pixels to apply the cleaning", + " in the 3 brightest pixels to apply the cleaning. Set to None if no" + " `bright_cleaning` should be applied.", + allow_none=True, ).tag(config=True) largest_island_only = BoolTelescopeParameter( default_value=False, help="Set to true to get only largest island" ).tag(config=True) - apply_pedestal_cleaning = BoolTelescopeParameter( - default_value=True, help="Set to true if pedestal cleaning should be applied" - ).tag(config=True) - pedestal_factor = FloatTelescopeParameter( default_value=2.5, help="Factor for interleaved pedestal cleaning. It is multiplied by the" @@ -789,14 +771,11 @@ def __call__( boundary_thresh=self.boundary_threshold_pe.tel[tel_id], min_number_picture_neighbors=self.min_picture_neighbors.tel[tel_id], keep_isolated_pixels=self.keep_isolated_pixels.tel[tel_id], - apply_time_cleaning=self.apply_time_cleaning.tel[tel_id], time_limit=self.time_limit.tel[tel_id], time_num_neighbors=self.time_num_neighbors.tel[tel_id], - apply_bright_cleaning=self.apply_bright_cleaning.tel[tel_id], bright_cleaning_fraction=self.bright_cleaning_fraction.tel[tel_id], bright_cleaning_threshold=self.bright_cleaning_threshold.tel[tel_id], largest_island_only=self.largest_island_only.tel[tel_id], - apply_pedestal_cleaning=self.apply_pedestal_cleaning.tel[tel_id], pedestal_factor=self.pedestal_factor.tel[tel_id], pedestal_std=pedestal_std, ) diff --git a/src/ctapipe/image/tests/test_cleaning.py b/src/ctapipe/image/tests/test_cleaning.py index 55c6cb0a336..56ab663cc40 100644 --- a/src/ctapipe/image/tests/test_cleaning.py +++ b/src/ctapipe/image/tests/test_cleaning.py @@ -501,13 +501,10 @@ def test_lst_image_cleaning(prod5_lst): "picture_thresh": 45, "boundary_thresh": 20, "keep_isolated_pixels": True, - "apply_time_cleaning": False, - "time_limit": 3, - "apply_bright_cleaning": False, + "time_limit": None, "bright_cleaning_fraction": 0.9, - "bright_cleaning_threshold": 40, + "bright_cleaning_threshold": None, "largest_island_only": False, - "apply_pedestal_cleaning": False, "pedestal_factor": 2, "pedestal_std": None, } @@ -521,7 +518,6 @@ def test_lst_image_cleaning(prod5_lst): # charge std. pedestal_std = np.ones(geom.n_pixels) pedestal_std[core_pixel_1] = 30 - args["apply_pedestal_cleaning"] = True args["pedestal_std"] = pedestal_std mask = cleaning.lst_image_cleaning(geom, charge, peak_time, **args) @@ -539,16 +535,16 @@ def test_lst_image_cleaning(prod5_lst): # deselect core_pixel_1 with time_delta_cleaning by setting all its neighbors # peak_time to 10 peak_time[neighbors_1] = 10 - args["apply_pedestal_cleaning"] = False - args["apply_time_cleaning"] = True + args["pedestal_std"] = None + args["time_limit"] = 3 mask = cleaning.lst_image_cleaning(geom, charge, peak_time, **args) assert np.count_nonzero(mask) == 1 + 6 + 6 # 3 brightest pixels are [50, 50, 29], so mean is 43. With a fraction of 0.9 # all boundaries should be deselected - args["apply_time_cleaning"] = False - args["apply_bright_cleaning"] = True + args["time_limit"] = None + args["bright_cleaning_threshold"] = 40 mask = cleaning.lst_image_cleaning(geom, charge, peak_time, **args) assert np.count_nonzero(mask) == 1 + 1 @@ -556,7 +552,7 @@ def test_lst_image_cleaning(prod5_lst): # Set neighbors of core_pixel_2 to 0 so largest_island_only should select only # core_pixel_1 with its neighbors charge[neighbors_2] = 0 - args["apply_bright_cleaning"] = False + args["bright_cleaning_threshold"] = None args["largest_island_only"] = True mask = cleaning.lst_image_cleaning(geom, charge, peak_time, **args) diff --git a/src/ctapipe/image/tests/test_image_cleaner_component.py b/src/ctapipe/image/tests/test_image_cleaner_component.py index cb3bb532c87..d2d443c4bbf 100644 --- a/src/ctapipe/image/tests/test_image_cleaner_component.py +++ b/src/ctapipe/image/tests/test_image_cleaner_component.py @@ -19,9 +19,8 @@ def test_image_cleaner(method, prod5_mst_nectarcam, reference_location): "LSTImageCleaner": { "boundary_threshold_pe": 5.0, "picture_threshold_pe": 10.0, - "apply_time_cleaning": False, - "apply_bright_cleaning": False, - "apply_pedestal_cleaning": False, + "time_limit": None, + "bright_cleaning_threshold": None, }, "MARSImageCleaner": { "boundary_threshold_pe": 5.0,