diff --git a/src/kbmod/configuration.py b/src/kbmod/configuration.py index ee6b7fc7..c17733e7 100644 --- a/src/kbmod/configuration.py +++ b/src/kbmod/configuration.py @@ -87,7 +87,7 @@ def __str__(self): result += f"{key}: {value}\n" return result - def set(self, param, value): + def set(self, param, value, warn_on_unknown=False): """Sets the value of a specific parameter. Parameters @@ -96,8 +96,10 @@ def set(self, param, value): The parameter name. value : any The parameter's value. + warn_on_unknown : `bool` + Generate a warning if the parameter is not known. """ - if param not in self._params: + if warn_on_unknown and param not in self._params: logger.warning(f"Setting unknown parameter: {param}") self._params[param] = value diff --git a/src/kbmod/search/layered_image.cpp b/src/kbmod/search/layered_image.cpp index e9c6e3b3..50baaeda 100644 --- a/src/kbmod/search/layered_image.cpp +++ b/src/kbmod/search/layered_image.cpp @@ -113,69 +113,6 @@ void LayeredImage::apply_mask(int flags) { variance.apply_mask(flags, mask); } -void LayeredImage::union_masks(RawImage& new_mask) { - const uint64_t num_pixels = get_npixels(); - assert_sizes_equal(new_mask.get_width(), width, "global mask width"); - assert_sizes_equal(new_mask.get_height(), height, "global mask height"); - - float* mask_pixels = mask.data(); - float* new_pixels = new_mask.data(); - for (uint64_t i = 0; i < num_pixels; ++i) { - int current_flags = static_cast(mask_pixels[i]); - int new_flags = static_cast(new_pixels[i]); - - // Use a bitwise OR to keep flags set in the current pixel or the new mask. - mask_pixels[i] = current_flags | new_flags; - } -} - -void LayeredImage::union_threshold_masking(float thresh) { - const uint64_t num_pixels = get_npixels(); - float* sci_pixels = science.data(); - float* mask_pixels = mask.data(); - - for (uint64_t i = 0; i < num_pixels; ++i) { - if (sci_pixels[i] > thresh) { - // Use a logical OR to preserve all other flags. - mask_pixels[i] = static_cast(mask_pixels[i]) | 1; - } - } -} - -/* This implementation of grow_mask is optimized for steps > 1 - (which is how the code is generally used. If you are only - growing the mask by 1, the extra copy will be a little slower. -*/ -void LayeredImage::grow_mask(int steps) { - logging::getLogger("kbmod.search.layered_image") - ->debug("Growing mask by " + std::to_string(steps) + " steps."); - - ImageI bitmask = ImageI::Constant(height, width, -1); - bitmask = (mask.get_image().array() > 0).select(0, bitmask); - - for (int itr = 1; itr <= steps; ++itr) { - for (int j = 0; j < height; ++j) { - for (int i = 0; i < width; ++i) { - if (bitmask(j, i) == -1) { - if (((j - 1 >= 0) && (bitmask(j - 1, i) == itr - 1)) || - ((i - 1 >= 0) && (bitmask(j, i - 1) == itr - 1)) || - ((j + 1 < height) && (bitmask(j + 1, i) == itr - 1)) || - ((i + 1 < width) && (bitmask(j, i + 1) == itr - 1))) { - bitmask(j, i) = itr; - } - } - } // for i - } // for j - } // for step - - // Overwrite the mask with the expanded one. - for (int j = 0; j < height; ++j) { - for (int i = 0; i < width; ++i) { - mask.set_pixel({j, i}, (bitmask(j, i) == -1) ? 0 : 1); - } - } -} - void LayeredImage::subtract_template(RawImage& sub_template) { assert_sizes_equal(sub_template.get_width(), width, "template width"); assert_sizes_equal(sub_template.get_height(), height, "template height"); @@ -350,9 +287,6 @@ static void layered_image_bindings(py::module& m) { }) .def("binarize_mask", &li::binarize_mask, pydocs::DOC_LayeredImage_binarize_mask) .def("apply_mask", &li::apply_mask, pydocs::DOC_LayeredImage_apply_mask) - .def("union_masks", &li::union_masks, pydocs::DOC_LayeredImage_union_masks) - .def("union_threshold_masking", &li::union_threshold_masking, - pydocs::DOC_LayeredImage_union_threshold_masking) .def("sub_template", &li::subtract_template, pydocs::DOC_LayeredImage_sub_template) .def("get_science", &li::get_science, py::return_value_policy::reference_internal, pydocs::DOC_LayeredImage_get_science) @@ -365,7 +299,6 @@ static void layered_image_bindings(py::module& m) { .def("set_variance", &li::set_variance, pydocs::DOC_LayeredImage_set_variance) .def("convolve_psf", &li::convolve_psf, pydocs::DOC_LayeredImage_convolve_psf) .def("convolve_given_psf", &li::convolve_given_psf, pydocs::DOC_LayeredImage_convolve_given_psf) - .def("grow_mask", &li::grow_mask, pydocs::DOC_LayeredImage_grow_mask) .def("get_width", &li::get_width, pydocs::DOC_LayeredImage_get_width) .def("get_height", &li::get_height, pydocs::DOC_LayeredImage_get_height) .def("get_npixels", &li::get_npixels, pydocs::DOC_LayeredImage_get_npixels) diff --git a/src/kbmod/search/layered_image.h b/src/kbmod/search/layered_image.h index 6e2eaa5c..d30127c8 100644 --- a/src/kbmod/search/layered_image.h +++ b/src/kbmod/search/layered_image.h @@ -65,9 +65,6 @@ class LayeredImage { // Masking functions. void mask_pixel(const Index& idx); void binarize_mask(int flags_to_keep); - void union_masks(RawImage& new_mask); - void union_threshold_masking(float thresh); - void grow_mask(int steps); void apply_mask(int flags); // Subtracts a template image from the science layer. diff --git a/src/kbmod/search/pydocs/layered_image_docs.h b/src/kbmod/search/pydocs/layered_image_docs.h index 876c8d34..6691d49d 100644 --- a/src/kbmod/search/pydocs/layered_image_docs.h +++ b/src/kbmod/search/pydocs/layered_image_docs.h @@ -64,26 +64,6 @@ static const auto DOC_LayeredImage_apply_mask = R"doc( call binarize_mask() first. )doc"; -static const auto DOC_LayeredImage_union_masks = R"doc( - Unions the masked pixel flags from the a given second mask layer onto - this image's mask layer. Modifies the mask layer in place. - - Parameters - ---------- - global_mask : `RawImage` - The `RawImage` of global mask values (binary) for each pixel. - )doc"; - -static const auto DOC_LayeredImage_union_threshold_masking = R"doc( - Masks any pixel whose corresponding value in the science layer is - above the given threshold using mask flag = 1. - - Parameters - ---------- - thresh : `float` - The threshold value to use. - )doc"; - static const auto DOC_LayeredImage_sub_template = R"doc( Subtract given image template )doc"; @@ -127,16 +107,6 @@ static const auto DOC_LayeredImage_convolve_given_psf = R"doc( The PSF to use. )doc"; -static const auto DOC_LayeredImage_grow_mask = R"doc( - Expands the NO_DATA tags to nearby pixels in the science and variance layers. - Modifies the images in-place. - - Parameters - ---------- - steps : `int` - The number of pixels by which to grow the masked regions. - )doc"; - static const auto DOC_LayeredImage_get_width = R"doc( Returns the image's width in pixels. )doc"; diff --git a/tests/test_layered_image.py b/tests/test_layered_image.py index a9e45698..493085a7 100644 --- a/tests/test_layered_image.py +++ b/tests/test_layered_image.py @@ -215,60 +215,6 @@ def test_binarize_mask(self): self.assertEqual(mask.get_pixel(10, 7), 1) self.assertEqual(mask.get_pixel(10, 8), 0) - def test_union_masks(self): - # Mask out a range of pixels. - mask = self.image.get_mask() - mask.set_pixel(15, 12, 1) - mask.set_pixel(15, 13, 2) - mask.set_pixel(15, 14, 3) - - mask2 = RawImage(mask.width, mask.height) - mask2.set_all(0.0) - mask2.set_pixel(15, 11, 1) - mask2.set_pixel(15, 13, 1) - mask2.set_pixel(15, 14, 1) - mask2.set_pixel(15, 15, 8) - - self.image.union_masks(mask2) - self.assertEqual(mask.get_pixel(15, 10), 0) - self.assertEqual(mask.get_pixel(15, 11), 1) # bit 1 added - self.assertEqual(mask.get_pixel(15, 12), 1) - self.assertEqual(mask.get_pixel(15, 13), 3) # bit 1 added - self.assertEqual(mask.get_pixel(15, 14), 3) - self.assertEqual(mask.get_pixel(15, 15), 8) - self.assertEqual(mask.get_pixel(15, 16), 0) - - def test_add_threshold_mask_flags(self): - masked_pixels = {} - threshold = 20.0 - - # Add an object brighter than the threshold. - add_fake_object(self.image, 50, 50, 500.0, self.p) - - # Manually find all the pixels that should be masked. - science = self.image.get_science() - for y in range(self.image.get_height()): - for x in range(self.image.get_width()): - value = science.get_pixel(y, x) - if value > threshold: - index = self.image.get_width() * y + x - masked_pixels[index] = True - self.assertGreater(len(masked_pixels), 0) - - # Reset the mask and perform threshold masking. - mask = self.image.get_mask() - mask.set_all(0.0) - self.image.union_threshold_masking(threshold) - - # Check that we masked the correct pixels. - for y in range(self.image.get_height()): - for x in range(self.image.get_width()): - index = self.image.get_width() * y + x - if index in masked_pixels: - self.assertEqual(mask.get_pixel(y, x), 1) - else: - self.assertEqual(mask.get_pixel(y, x), 0) - def test_apply_mask(self): # Nothing is initially masked. science = self.image.get_science() @@ -293,38 +239,6 @@ def test_apply_mask(self): else: self.assertTrue(science.pixel_has_data(y, x)) - def test_grow_mask(self): - mask = self.image.get_mask() - mask.set_pixel(11, 10, 1) - mask.set_pixel(12, 10, 1) - mask.set_pixel(13, 10, 1) - self.image.grow_mask(1) - - # Check that the mask has grown to all adjacent pixels. - for y in range(self.image.get_height()): - for x in range(self.image.get_width()): - should_mask = ( - (x == 10 and y <= 14 and y >= 10) - or (x == 9 and y <= 13 and y >= 11) - or (x == 11 and y <= 13 and y >= 11) - ) - self.assertEqual(mask.get_pixel(y, x) == 0, not should_mask) - - def test_grow_mask_mult(self): - mask = self.image.get_mask() - mask.set_pixel(11, 10, 1) - mask.set_pixel(12, 10, 1) - self.image.grow_mask(3) - - # Check that the mask has grown to all applicable pixels. - for y in range(self.image.get_height()): - for x in range(self.image.get_width()): - # Check whether the point is a manhattan distance of <= 3 from - # one of the original masked pixels. - dx = abs(x - 10) - dy = min(abs(y - 11), abs(y - 12)) - self.assertEqual(mask.get_pixel(y, x) == 0, dx + dy > 3) - def test_psi_and_phi_image(self): p = PSF(0.00000001) # A point function. img = make_fake_layered_image(6, 5, 2.0, 4.0, 10.0, p)