Skip to content

Commit

Permalink
Add clamp option
Browse files Browse the repository at this point in the history
Optionally ensure that min and max are withon floor and limit.
  • Loading branch information
blowekamp committed Aug 19, 2022
1 parent 3feffbd commit 3f60b07
Show file tree
Hide file tree
Showing 3 changed files with 34 additions and 11 deletions.
10 changes: 9 additions & 1 deletion pytools/ng/build_histogram.py
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,11 @@ def histogram_stats(hist, bin_edges):
mutually_exclusive=["sigma", "mad"],
help="Use INPUT_IMAGE's middle percentile (option's value) of data for minimum and maximum range.",
)
@click.option(
"--clamp/--no-clamp",
default=False,
help="Clamps minimum and maximum range to existing intensity values (floor and limit).",
)
@click.option(
"--output-json",
type=click.Path(exists=False, dir_okay=False, resolve_path=True),
Expand All @@ -175,7 +180,7 @@ def histogram_stats(hist, bin_edges):
"elements of a double numeric value.",
)
@click.version_option(__version__)
def main(input_image, mad, sigma, percentile, output_json):
def main(input_image, mad, sigma, percentile, clamp, output_json):
"""
Reads the INPUT_IMAGE to compute an estimated minimum and maximum range to be used for visualization of the
data set. The image is required to have an integer pixel type.
Expand Down Expand Up @@ -247,6 +252,9 @@ def main(input_image, mad, sigma, percentile, output_json):

floor_limit = weighted_quantile(mids, quantiles=[0.0, 1.0], sample_weight=h, values_sorted=True)

if clamp:
min_max = (max(min_max[0], floor_limit[0]), min(min_max[1], floor_limit[1]))

output = {
"neuroglancerPrecomputedMin": str(floor(min_max[0])),
"neuroglancerPrecomputedMax": str(ceil(min_max[1])),
Expand Down
12 changes: 11 additions & 1 deletion test/fixtures.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@

@pytest.fixture(
scope="session",
params=[sitk.sitkUInt8, sitk.sitkInt16, sitk.sitkUInt16, sitk.sitkFloat32, "uint16_uniform"],
params=[sitk.sitkUInt8, sitk.sitkInt16, sitk.sitkUInt16, sitk.sitkFloat32, "uint16_uniform", "uint8_bimodal"],
)
def image_mrc(request, tmp_path_factory):
if isinstance(request.param, str) and request.param == "uint16_uniform":
Expand All @@ -29,6 +29,16 @@ def image_mrc(request, tmp_path_factory):
a = np.linspace(0, 2**16 - 1, num=2**16, dtype="uint16").reshape(16, 64, 64)
img = sitk.GetImageFromArray(a)
img.SetSpacing([1.23, 1.23, 4.96])

elif isinstance(request.param, str) and request.param == "uint8_bimodal":

print(f"Calling image_mrc with {request.param}")
fn = f"image_mrc_{request.param.replace(' ', '_')}.mrc"

a = np.zeros([16, 16, 16], np.uint8)
a[len(a) // 2 :] = 255
img = sitk.GetImageFromArray(a)
img.SetSpacing([12.3, 12.3, 56.7])
else:
pixel_type = request.param
print(f"Calling image_mrc with {sitk.GetPixelIDValueAsString(pixel_type)}")
Expand Down
23 changes: 14 additions & 9 deletions test/test_histogram.py
Original file line number Diff line number Diff line change
Expand Up @@ -108,22 +108,27 @@ def test_histogram_mai_help(cli_args):


@pytest.mark.parametrize(
"image_mrc,expected_min, expected_max, expected_floor, expected_limit",
"image_mrc,expected_min, expected_max, expected_floor, expected_limit, clamp",
[
(sitk.sitkUInt8, 0, 0, 0, 0),
(sitk.sitkInt16, 0, 0, 0, 0),
(sitk.sitkUInt16, 0, 0, 0, 0),
("uint16_uniform", 8191, 57344, 0, 65535),
(sitk.sitkUInt8, 0, 0, 0, 0, False),
(sitk.sitkInt16, 0, 0, 0, 0, True),
(sitk.sitkUInt16, 0, 0, 0, 0, False),
("uint16_uniform", 8191, 57344, 0, 65535, True),
("uint16_uniform", 8191, 57344, 0, 65535, False),
("uint8_bimodal", 0, 255, 0, 255, True),
("uint8_bimodal", -64, 319, 0, 255, False),
],
indirect=["image_mrc"],
)
def test_build_histogram_main(image_mrc, expected_min, expected_max, expected_floor, expected_limit):
def test_build_histogram_main(image_mrc, expected_min, expected_max, expected_floor, clamp, expected_limit):
runner = CliRunner()
output_filename = "out.json"
args = [image_mrc, "--mad", "1.5", "--output-json", output_filename]
if clamp:
args.append("--clamp")
print(args)
with runner.isolated_filesystem():
result = runner.invoke(
pytools.ng.build_histogram.main, [image_mrc, "--mad", "1.5", "--output-json", output_filename]
)
result = runner.invoke(pytools.ng.build_histogram.main, args=args)
assert not result.exception
with open(output_filename) as fp:
res = json.load(fp)
Expand Down

0 comments on commit 3f60b07

Please sign in to comment.