# Fix asinh

XMLWordPrintable

#### Details

• Type: Bug
• Status: Done
• Resolution: Done
• Fix Version/s: None
• Component/s:
• Labels:
• Story Points:
8
• Sprint:
SUIT Sprint 2018-06, SUIT Sprint 2018-07
• Team:
Science User Interface

#### Description

We still do not have asinh quite right, the following should be done:

• Determine what is wrong, maybe why it is wrapping?
• Understand why have a beta parameter exposed to the user and not a Q parameter. You might want to talk to Lijun about this since she did the original work but no longer works for LSST.
• From the UI- determine if we we need a slider entry instead of a number text box entry. Note- when asinh was originally done we had not yet brought in a slider component. It makes more sense now.
• Work with David Shupe to validate the implementation plan
• FitsRead.java has most of the stretch code as static methods.  Move these out of FitsRead.java into a Stretch.java
• David Shupe thinks we have the same problem with Power law Gamma.  If that is a simple fix after the above work then fix it, otherwise we will make a second ticket.

6/25/2018

This ticket will deal with changing asinh algorithm to be consistent with asinh stretch implemented in https://github.com/lsst/afw/blob/master/python/lsst/afw/display/rgb.py and https://github.com/astropy/astropy/blob/master/astropy/visualization/lupton_rgb.py

The parametrization using Q is explained in the footnote on page 3 of https://arxiv.org/pdf/astro-ph/0312483.pdf

The algorithm will accept Q parameter from 0.1 to 10, which should be controlled by a slider.
The mapping from flux to color value is 255 * 0.1 * asinh(Q*(x-xMin)/(xMax-xMin)) / asinh(0.1*Q)

Below xMin, the color will be 0; above xMax, the equation has to be applied and then clipped to 244 (because we use 255 for blank pixel).

Per David Shupe

Zscale + linear is often used with CCD images to show faint features. I am thinking of Lupton’s asinh as keeping zscale + linear at low values, and bending the stretch function over at intermediate and large intensities. It uses only a fraction of the color range for the max value from zscale; but it will show brighter features above zscale.
Lupton’s formulation assumes that xMax is far below the bright features in the image. He wants to see the features above xMax as computed by zscale. This is different from how I have traditionally thought about these stretches.

________________

The first and last items in the original description above were fixed by DM-14780.

Stretch code will stay in FitsRead.java to avoid conflicts with Lijun's IRSA-1498 ticket, which takes care of code refactoring.

Per David Shupe, it would also be helpful to display boundaries, calculated by z-stretch algorithm rather than the original data boundaries. I will see if I can add the calculated values to z-stretch dialog.

#### Attachments

1. image (3).png
1.06 MB
2. image (4).png
1.00 MB
3. lupton_asinh_example.png
37 kB

#### Activity

Hide
Trey Roby added a comment -

Notes from Robert Lupton

I asked for an disp.scale(asinh, zscale) image which should not saturate at any point.  Why the roll over?

asinh should be your go-to stretch!  If you set Q = 0 you recover linear; Q = InF gets you log.  Q = 10 or so is better than either.  Firefly needs a Q slider

Notes from Jim Bosch

Jim Bosch [6:56 AM]
I think this can probably be reproduced without any particular image; when trying asinh stretches in the GUI, the colorbar always seemed to have some periodicity to it, and I think that's the same thing that's causing this.
It may only happen when the data range is set beyond the min/max of what is actually in the image, but I'm trying to reconstruct what I saw from memory, so take it with a grain of salt.

Show
Trey Roby added a comment - Notes from Robert Lupton  I asked for an disp.scale(asinh, zscale) image which should not saturate at any point.  Why the roll over? asinh should be your go-to stretch!  If you set Q = 0 you recover linear; Q = InF gets you log.  Q = 10 or so is better than either.  Firefly needs a Q slider   Notes from Jim Bosch Jim Bosch [6:56 AM] I think this can probably be reproduced without any particular image; when trying asinh stretches in the GUI, the colorbar always seemed to have some periodicity to it, and I think that's the same thing that's causing this. It may only happen when the data range is set beyond the min/max of what is actually in the image, but I'm trying to reconstruct what I saw from memory, so take it with a grain of salt.
Hide
David Shupe added a comment - - edited

As I recall, the asinh implementation in Firefly is based on code in the IDL atv tool. I think our beta is dataRange / Q, the reciprocal of ._soften in lsst.afw.display.rgb.AsinhMapping.

Our default beta is estimated from noise properties of the image. beta is exposed at the FireflyClient level but not exposed at the display_firefly or FireflyClient levels, right now.

Show
David Shupe added a comment - - edited As I recall, the asinh implementation in Firefly is based on code in the IDL atv tool. I think our beta is dataRange / Q , the reciprocal of ._soften in lsst.afw.display.rgb.AsinhMapping . Our default beta is estimated from noise properties of the image. beta is exposed at the FireflyClient level but not exposed at the display_firefly or FireflyClient levels, right now.
Hide
Tatiana Goldina added a comment -

Our default beta is a standard deviation: sigma = SQRT [ sum ((x_i - x_mean)^2 ) / n ], where x_mean is the mean value of the x array and  n is the total number of the elements in x array.

The mapping function from (xMin, xMax)  to (0, 255) is

 F(x) = 255 * asinh((x - xMin) / beta) / asinh((xMax - xMin) / beta) 

Is it how we want it? I am still not clear what the meaning of Q is, and what should be its range, if we make it a slider.

Show
Tatiana Goldina added a comment - Our default beta is a standard deviation:  sigma = SQRT [ sum ((x_i - x_mean)^2 ) / n ] , where x_mean is the mean value of the x array and  n is the total number of the elements in x array. The mapping function from (xMin, xMax)  to (0, 255) is F(x) = 255 * asinh((x - xMin) / beta) / asinh((xMax - xMin) / beta) Is it how we want it? I am still not clear what the meaning of Q is, and what should be its range, if we make it a slider.
Hide
Robert Lupton added a comment -

Look at the original PASP paper, which defines Q.

I don't think you want to set Q from the data, you want to set xMax and xMin (e.g. I support 'asinh', 'zscale' for matplotlib); Q controls the transition from a linear to a logarithmic stretch and typical numbers are 8 to 10.  I think a slider is the way to allow people to control this.

I was surprised to learn that Q isn't exposed in display_firefly; I should have been clearer about the interface.

Show
Robert Lupton added a comment - Look at the original PASP paper, which defines Q. I don't think you want to set Q from the data, you want to set xMax and xMin (e.g. I support  'asinh', 'zscale'  for matplotlib); Q controls the transition from a linear to a logarithmic stretch and typical numbers are 8 to 10.  I think a slider is the way to allow people to control this. I was surprised to learn that Q isn't exposed in display_firefly ; I should have been clearer about the interface.
Hide
David Shupe added a comment -

Tatiana Goldina and I have been looking at the asinh implementations in lsst.afw.display.rgb and in astropy.visualization.lupton_rgb which uses some of the same classes as the LSST code. We think we understand what to implement and we'd like to check our understanding with Robert Lupton,  since these implementations are slightly different from the 2004 PASP paper.

The mapping from image values x to the uint8 will be 255 * asinh(0.1*Q*(x-xMin)/(xMax-xMin)) / asinh(0.1*Q). It is not necessary to specify a separate slope parameter, because the choice of xMax and xMin set the slope at intensities near zero. This parametrization works well with using the zscale algorithm to set xMin and xMax, from looking at HSC data with the display_matplotlib backend.

Do we have this right?

Show
David Shupe added a comment - Tatiana Goldina and I have been looking at the asinh implementations in lsst.afw.display.rgb and in astropy.visualization.lupton_rgb which uses some of the same classes as the LSST code. We think we understand what to implement and we'd like to check our understanding with Robert Lupton ,  since these implementations are slightly different from the 2004 PASP paper. The mapping from image values x to the uint8 will be 255 * asinh(0.1*Q*(x-xMin)/(xMax-xMin)) / asinh(0.1*Q) . It is not necessary to specify a separate slope parameter, because the choice of xMax and xMin set the slope at intensities near zero. This parametrization works well with using the zscale algorithm to set xMin and xMax, from looking at HSC data with the display_matplotlib backend. Do we have this right?
Hide
Robert Lupton added a comment -

That sounds right – thanks.  You still need to be able to set Q independently

Show
Robert Lupton added a comment - That sounds right – thanks.  You still need to be able to set Q independently
Hide
Tatiana Goldina added a comment -
Show
Tatiana Goldina added a comment - Pull request: https://github.com/Caltech-IPAC/firefly/pull/632 Deployment:  https://irsawebdev9.ipac.caltech.edu/dm-14778/firefly/
Hide
David Shupe added a comment -

I've summarized feedback from Vandana Desai on the pull request.

Show
David Shupe added a comment - I've summarized feedback from Vandana Desai on the pull request.

#### People

Assignee:
Tatiana Goldina
Reporter:
Trey Roby
Reviewers:
David Shupe, Trey Roby, Vandana Desai
Watchers:
David Shupe, Emmanuel Joliet, Jim Bosch, Robert Lupton, Tatiana Goldina, Trey Roby, Vandana Desai, Xiuqin Wu [X] (Inactive)