From a22201944248c365879970c02e284965c98bd884 Mon Sep 17 00:00:00 2001 From: Steven Crawford Date: Thu, 4 Oct 2018 13:39:17 -0400 Subject: [PATCH 1/8] Added the option to overplot --- wfc3tools/pstat.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/wfc3tools/pstat.py b/wfc3tools/pstat.py index 6901a8c..2e313eb 100644 --- a/wfc3tools/pstat.py +++ b/wfc3tools/pstat.py @@ -15,10 +15,10 @@ __taskname__ = "pstat" -plt.ion() +#plt.ion() def pstat(filename, extname="sci", units="counts", stat="midpt", title=None, - xlabel=None, ylabel=None, plot=True): + xlabel=None, ylabel=None, plot=True, overplot=False): """A function to plot the statistics of one or more pixels up an IR ramp. Pixel values here are 0 based, not 1 based """ @@ -127,7 +127,7 @@ def pstat(filename, extname="sci", units="counts", stat="midpt", title=None, yaxis[i-1] *= exptime if plot: - plt.clf() # clear out any current plot + if not overplot: plt.clf() # clear out any current plot if not ylabel: if "rate" in units.lower(): if "/" in bunit.lower(): From 56dc860c674c8fc6f1fb7c756fe16ae6f1e3f340 Mon Sep 17 00:00:00 2001 From: Steven Crawford Date: Thu, 4 Oct 2018 14:06:56 -0400 Subject: [PATCH 2/8] update the help information for pstat --- wfc3tools/pstat.help | 4 ++ wfc3tools/pstat.py | 102 ++++++++++++++++++++++++++++++++++--------- 2 files changed, 86 insertions(+), 20 deletions(-) diff --git a/wfc3tools/pstat.help b/wfc3tools/pstat.help index 00c72d3..53c68b8 100644 --- a/wfc3tools/pstat.help +++ b/wfc3tools/pstat.help @@ -92,6 +92,10 @@ Parameters: * plot = True [bool] set plot to false if you only want the data returned +* overplot = False [bool] + If True, the results will be overplotted on the previous plot + + Usage: :: diff --git a/wfc3tools/pstat.py b/wfc3tools/pstat.py index 2e313eb..b16db6c 100644 --- a/wfc3tools/pstat.py +++ b/wfc3tools/pstat.py @@ -15,13 +15,65 @@ __taskname__ = "pstat" -#plt.ion() +plt.ion() + def pstat(filename, extname="sci", units="counts", stat="midpt", title=None, xlabel=None, ylabel=None, plot=True, overplot=False): """A function to plot the statistics of one or more pixels up an IR ramp. - Pixel values here are 0 based, not 1 based """ + Parameters + ---------- + filename: string + Input MultiAccum image name with optional image section + specification. If no image section is specified, the entire image + is used. This should be either a _raw or _ima file, containing all + the data from multiple readouts. You must specify just the + file name and image section, with no extname designation. + + extname: {"sci", "err", "dq"} + Extension name (EXTNAME keyword value) of data to plot. + + units: {"counts", "rate"} + Plot "sci" or "err" data in units of counts or countrate + ("rate"). Input data can be in either unit; conversion will be + performed automatically. Ignored when plotting "dq", "samp", or + "time" data. + + stat: { "mean", "midpt", "mode", "stddev", "min", "max"} + Type of statistic to compute. + + title: str + Title for the plot. If left blank, the name of the input image, + appended with the extname and image section, is used. + + xlabel: str + Label for the X-axis of the plot. If left blank, a suitable default + is generated. + + ylabel: str + Label for the Y-axis of the plot. If left blank, a suitable default + based on the plot units and the extname of the data is generated. + + plot: Bool + Set plot to false if you only want the data returned + + overplot: Bool + If True, the results will be overplotted on the previous plot + + Returns + ------- + xaxis: numpy.ndarray + Array of x-axis values that will be plotted + + yaxis: numpuy.ndarray + Array of y-axis values that will be plotted as specified by 'units' + + + Notes + ----- + Pixel values here are 0 based, not 1 based + """ # pull the image extension from the filename string section_start = filename.find("[") @@ -31,8 +83,8 @@ def pstat(filename, extname="sci", units="counts", stat="midpt", title=None, imagename = filename elif (section_start > 0): imagename = filename[:section_start] - if (filename[section_start+1].isalpha()): - print(filename[section_start+1]) + if (filename[section_start + 1].isalpha()): + print(filename[section_start + 1]) print("Please only specify a pixel range, not an extension \ in the filename") return 0, 0 @@ -51,10 +103,10 @@ def pstat(filename, extname="sci", units="counts", stat="midpt", title=None, # use the entire image if no section specified if not all_pixels: # pull the section off - section = filename[section_start+1:-1] + section = filename[section_start + 1:-1] comma = section.find(",") xsec = section[:comma] - ysec = section[comma+1:] + ysec = section[comma + 1:] xs = xsec.find(":") if xs < 0: print("Invalid image section specified") @@ -65,7 +117,7 @@ def pstat(filename, extname="sci", units="counts", stat="midpt", title=None, print("Problem getting xstart") return try: - xend = int(xsec[xs+1:]) + xend = int(xsec[xs + 1:]) except ValueError: print("Problem getting xend") return @@ -80,7 +132,7 @@ def pstat(filename, extname="sci", units="counts", stat="midpt", title=None, print("Problems getting ystart") return try: - yend = int(ysec[ys+1:]) + yend = int(ysec[ys + 1:]) except ValueError: print("Problem getting yend") return @@ -99,41 +151,50 @@ def pstat(filename, extname="sci", units="counts", stat="midpt", title=None, for i in range(1, nsamp, 1): if "midpt" in stat: - yaxis[i-1] = np.median(myfile[extname.upper(), i].data[xstart:xend, ystart:yend]) + yaxis[i - 1] = np.median(myfile[extname.upper(), + i].data[xstart:xend, ystart:yend]) if "mean" in stat: - yaxis[i-1] = np.mean(myfile[extname.upper(), i].data[xstart:xend, ystart:yend]) + yaxis[i - 1] = np.mean(myfile[extname.upper(), + i].data[xstart:xend, ystart:yend]) if "mode" in stat: - yaxis[i-1] = mode(myfile[extname.upper(), i].data[xstart:xend, ystart:yend], axis=None)[0] + yaxis[i - 1] = mode(myfile[extname.upper(), + i].data[xstart:xend, + ystart:yend], + axis=None)[0] if "min" in stat: - yaxis[i-1] = np.min(myfile[extname.upper(), i].data[xstart:xend, ystart:yend]) + yaxis[i - 1] = np.min(myfile[extname.upper(), + i].data[xstart:xend, ystart:yend]) if "max" in stat: - yaxis[i-1] = np.max(myfile[extname.upper(), i].data[xstart:xend, ystart:yend]) + yaxis[i - 1] = np.max(myfile[extname.upper(), + i].data[xstart:xend, ystart:yend]) if "stddev" in stat: - yaxis[i-1] = np.std(myfile[extname.upper(), i].data[xstart:xend, ystart:yend]) + yaxis[i - 1] = np.std(myfile[extname.upper(), + i].data[xstart:xend, ystart:yend]) - exptime=myfile["SCI",i ].header['SAMPTIME'] - xaxis[i-1] = exptime + exptime = myfile["SCI", i].header['SAMPTIME'] + xaxis[i - 1] = exptime # convert to countrate if "rate" in units.lower() and "/" not in bunit.lower(): - yaxis[i-1] /= exptime + yaxis[i - 1] /= exptime # convert to counts if "counts" in units.lower() and "/" in bunit.lower(): - yaxis[i-1] *= exptime + yaxis[i - 1] *= exptime if plot: - if not overplot: plt.clf() # clear out any current plot + if not overplot: + plt.clf() # clear out any current plot if not ylabel: if "rate" in units.lower(): if "/" in bunit.lower(): ylabel = bunit else: - ylabel = bunit+" per second" + ylabel = bunit + " per second" else: if "/" in bunit: stop_index = bunit.find("/") @@ -190,4 +251,5 @@ def help(file=None): f.write(helpstr) f.close() + pstat.__doc__ = getHelpAsString(docstring=True) From 2ca008c37a37e912d4db26e8aa911baa7a1da613 Mon Sep 17 00:00:00 2001 From: Steven Crawford Date: Thu, 4 Oct 2018 14:11:43 -0400 Subject: [PATCH 3/8] updates to formating --- wfc3tools/pstat.py | 37 +++++++++++++++---------------------- 1 file changed, 15 insertions(+), 22 deletions(-) diff --git a/wfc3tools/pstat.py b/wfc3tools/pstat.py index b16db6c..dce6a2e 100644 --- a/wfc3tools/pstat.py +++ b/wfc3tools/pstat.py @@ -83,8 +83,8 @@ def pstat(filename, extname="sci", units="counts", stat="midpt", title=None, imagename = filename elif (section_start > 0): imagename = filename[:section_start] - if (filename[section_start + 1].isalpha()): - print(filename[section_start + 1]) + if (filename[section_start+1].isalpha()): + print(filename[section_start+1]) print("Please only specify a pixel range, not an extension \ in the filename") return 0, 0 @@ -103,10 +103,10 @@ def pstat(filename, extname="sci", units="counts", stat="midpt", title=None, # use the entire image if no section specified if not all_pixels: # pull the section off - section = filename[section_start + 1:-1] + section = filename[section_start+1:-1] comma = section.find(",") xsec = section[:comma] - ysec = section[comma + 1:] + ysec = section[comma+1:] xs = xsec.find(":") if xs < 0: print("Invalid image section specified") @@ -117,7 +117,7 @@ def pstat(filename, extname="sci", units="counts", stat="midpt", title=None, print("Problem getting xstart") return try: - xend = int(xsec[xs + 1:]) + xend = int(xsec[xs+1:]) except ValueError: print("Problem getting xend") return @@ -132,7 +132,7 @@ def pstat(filename, extname="sci", units="counts", stat="midpt", title=None, print("Problems getting ystart") return try: - yend = int(ysec[ys + 1:]) + yend = int(ysec[ys+1:]) except ValueError: print("Problem getting yend") return @@ -151,40 +151,33 @@ def pstat(filename, extname="sci", units="counts", stat="midpt", title=None, for i in range(1, nsamp, 1): if "midpt" in stat: - yaxis[i - 1] = np.median(myfile[extname.upper(), - i].data[xstart:xend, ystart:yend]) + yaxis[i-1] = np.median(myfile[extname.upper(), i].data[xstart:xend, ystart:yend]) if "mean" in stat: - yaxis[i - 1] = np.mean(myfile[extname.upper(), - i].data[xstart:xend, ystart:yend]) + yaxis[i-1] = np.mean(myfile[extname.upper(), i].data[xstart:xend, ystart:yend]) if "mode" in stat: - yaxis[i - 1] = mode(myfile[extname.upper(), - i].data[xstart:xend, - ystart:yend], + yaxis[i-1] = mode(myfile[extname.upper(),i].data[xstart:xend, ystart:yend], axis=None)[0] if "min" in stat: - yaxis[i - 1] = np.min(myfile[extname.upper(), - i].data[xstart:xend, ystart:yend]) + yaxis[i-1] = np.min(myfile[extname.upper(), i].data[xstart:xend, ystart:yend]) if "max" in stat: - yaxis[i - 1] = np.max(myfile[extname.upper(), - i].data[xstart:xend, ystart:yend]) + yaxis[i-1] = np.max(myfile[extname.upper(), i].data[xstart:xend, ystart:yend]) if "stddev" in stat: - yaxis[i - 1] = np.std(myfile[extname.upper(), - i].data[xstart:xend, ystart:yend]) + yaxis[i-1] = np.std(myfile[extname.upper(), i].data[xstart:xend, ystart:yend]) exptime = myfile["SCI", i].header['SAMPTIME'] - xaxis[i - 1] = exptime + xaxis[i-1] = exptime # convert to countrate if "rate" in units.lower() and "/" not in bunit.lower(): - yaxis[i - 1] /= exptime + yaxis[i-1] /= exptime # convert to counts if "counts" in units.lower() and "/" in bunit.lower(): - yaxis[i - 1] *= exptime + yaxis[i-1] *= exptime if plot: if not overplot: From 15beec3d80f79a383077cf92ba3b97db43a0ca51 Mon Sep 17 00:00:00 2001 From: Steven Crawford Date: Thu, 4 Oct 2018 14:54:10 -0400 Subject: [PATCH 4/8] added masking for pstat --- wfc3tools/pstat.help | 5 +++++ wfc3tools/pstat.py | 30 +++++++++++++++++++----------- 2 files changed, 24 insertions(+), 11 deletions(-) diff --git a/wfc3tools/pstat.help b/wfc3tools/pstat.help index 53c68b8..c805186 100644 --- a/wfc3tools/pstat.help +++ b/wfc3tools/pstat.help @@ -77,6 +77,11 @@ Parameters: * stat = "midpt" [string, allowed values: mean|midpt|mode|stddev|min|max] Type of statistic to compute. +* mask = `numpy.ndarray` (bool), optional + A boolean mask with the same shape as ``data``, where a `True` + value indicates the corresponding element of ``data`` is masked. + Masked pixels are excluded when computing the statistics. + * title = "" [string] Title for the plot. If left blank, the name of the input image, appended with the extname and image section, is used. diff --git a/wfc3tools/pstat.py b/wfc3tools/pstat.py index dce6a2e..c0160b5 100644 --- a/wfc3tools/pstat.py +++ b/wfc3tools/pstat.py @@ -18,8 +18,8 @@ plt.ion() -def pstat(filename, extname="sci", units="counts", stat="midpt", title=None, - xlabel=None, ylabel=None, plot=True, overplot=False): +def pstat(filename, extname="sci", units="counts", stat="midpt", mask=None, + title=None, xlabel=None, ylabel=None, plot=True, overplot=False): """A function to plot the statistics of one or more pixels up an IR ramp. Parameters @@ -43,6 +43,11 @@ def pstat(filename, extname="sci", units="counts", stat="midpt", title=None, stat: { "mean", "midpt", "mode", "stddev", "min", "max"} Type of statistic to compute. + mask: `numpy.ndarray` (bool), optional + A boolean mask with the same shape as ``data``, where a `True` + value indicates the corresponding element of ``data`` is masked. + Masked pixels are excluded when computing the statistics. + title: str Title for the plot. If left blank, the name of the input image, appended with the extname and image section, is used. @@ -63,10 +68,10 @@ def pstat(filename, extname="sci", units="counts", stat="midpt", title=None, Returns ------- - xaxis: numpy.ndarray + xaxis: `numpy.ndarray` Array of x-axis values that will be plotted - yaxis: numpuy.ndarray + yaxis: `numpuy.ndarray` Array of y-axis values that will be plotted as specified by 'units' @@ -150,24 +155,27 @@ def pstat(filename, extname="sci", units="counts", stat="midpt", title=None, yend = myfile[1].header["NAXIS2"] # full y size for i in range(1, nsamp, 1): + data = myfile[extname.upper(), i].data[xstart:xend, ystart:yend] + if mask is not None: + data = data[~mask[xstart:xend, ystart:yend]] + if "midpt" in stat: - yaxis[i-1] = np.median(myfile[extname.upper(), i].data[xstart:xend, ystart:yend]) + yaxis[i-1] = np.median(data) if "mean" in stat: - yaxis[i-1] = np.mean(myfile[extname.upper(), i].data[xstart:xend, ystart:yend]) + yaxis[i-1] = np.mean(data) if "mode" in stat: - yaxis[i-1] = mode(myfile[extname.upper(),i].data[xstart:xend, ystart:yend], - axis=None)[0] + yaxis[i-1] = mode(data, axis=None)[0] if "min" in stat: - yaxis[i-1] = np.min(myfile[extname.upper(), i].data[xstart:xend, ystart:yend]) + yaxis[i-1] = np.min(data) if "max" in stat: - yaxis[i-1] = np.max(myfile[extname.upper(), i].data[xstart:xend, ystart:yend]) + yaxis[i-1] = np.max(data) if "stddev" in stat: - yaxis[i-1] = np.std(myfile[extname.upper(), i].data[xstart:xend, ystart:yend]) + yaxis[i-1] = np.std(data) exptime = myfile["SCI", i].header['SAMPTIME'] xaxis[i-1] = exptime From 7206c29b7ea30aa67f555fcbc26a772c25af8c3d Mon Sep 17 00:00:00 2001 From: Steven Crawford Date: Thu, 4 Oct 2018 14:56:40 -0400 Subject: [PATCH 5/8] white space fix --- wfc3tools/pstat.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wfc3tools/pstat.py b/wfc3tools/pstat.py index c0160b5..562f003 100644 --- a/wfc3tools/pstat.py +++ b/wfc3tools/pstat.py @@ -43,7 +43,7 @@ def pstat(filename, extname="sci", units="counts", stat="midpt", mask=None, stat: { "mean", "midpt", "mode", "stddev", "min", "max"} Type of statistic to compute. - mask: `numpy.ndarray` (bool), optional + mask: `numpy.ndarray` (bool), optional A boolean mask with the same shape as ``data``, where a `True` value indicates the corresponding element of ``data`` is masked. Masked pixels are excluded when computing the statistics. From 285a4a1b9fd259281badef40dd11cc5004819701 Mon Sep 17 00:00:00 2001 From: Steven Crawford Date: Thu, 4 Oct 2018 15:35:07 -0400 Subject: [PATCH 6/8] include upper and lower limit --- wfc3tools/pstat.py | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/wfc3tools/pstat.py b/wfc3tools/pstat.py index 562f003..6ebef9f 100644 --- a/wfc3tools/pstat.py +++ b/wfc3tools/pstat.py @@ -19,7 +19,8 @@ def pstat(filename, extname="sci", units="counts", stat="midpt", mask=None, - title=None, xlabel=None, ylabel=None, plot=True, overplot=False): + low_limit = None, high_limit = None, title=None, xlabel=None, + ylabel=None, plot=True, overplot=False): """A function to plot the statistics of one or more pixels up an IR ramp. Parameters @@ -48,6 +49,14 @@ def pstat(filename, extname="sci", units="counts", stat="midpt", mask=None, value indicates the corresponding element of ``data`` is masked. Masked pixels are excluded when computing the statistics. + low_limit: float, (optional) + If set, the statistics will be calculated using only pixels that are + above this value. + + high_limit: float, (optional) + If set, the statistics will be calculated using only pixels that are + below this value. + title: str Title for the plot. If left blank, the name of the input image, appended with the extname and image section, is used. @@ -156,9 +165,21 @@ def pstat(filename, extname="sci", units="counts", stat="midpt", mask=None, for i in range(1, nsamp, 1): data = myfile[extname.upper(), i].data[xstart:xend, ystart:yend] + + # mask the data and remove outlyier values if mask is not None: data = data[~mask[xstart:xend, ystart:yend]] + if high_limit is not None: + data = data[data < high_limit] + + if low_limit is not None: + data = data[data > low_limit] + + if data.size == 0: + print("No valid pixels in ext {} of {}".format(i, imagename)) + return xaxis, yaxis + if "midpt" in stat: yaxis[i-1] = np.median(data) From 2655c376608ec61b6544d4ce4816e07db1ae6e45 Mon Sep 17 00:00:00 2001 From: Steven Crawford Date: Thu, 4 Oct 2018 15:35:21 -0400 Subject: [PATCH 7/8] update to help for upper and lower limit --- wfc3tools/pstat.help | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/wfc3tools/pstat.help b/wfc3tools/pstat.help index c805186..45107fc 100644 --- a/wfc3tools/pstat.help +++ b/wfc3tools/pstat.help @@ -68,6 +68,7 @@ Parameters: * extname = "sci" [string, allowed values: sci | err | dq ] Extension name (EXTNAME keyword value) of data to plot. + * units = "counts" [string, allowed values: counts | rate] Plot "sci" or "err" data in units of counts or countrate ("rate"). Input data can be in either unit; conversion will be @@ -77,11 +78,20 @@ Parameters: * stat = "midpt" [string, allowed values: mean|midpt|mode|stddev|min|max] Type of statistic to compute. -* mask = `numpy.ndarray` (bool), optional +* mask = None [`numpy.ndarray` (bool), optional] A boolean mask with the same shape as ``data``, where a `True` value indicates the corresponding element of ``data`` is masked. Masked pixels are excluded when computing the statistics. +* low_limit = None [float, (optional)] + If set, the statistics will be calculated using only pixels that are + above this value. + +* high_limit = None [float, (optional)] + If set, the statistics will be calculated using only pixels that are + below this value. + + * title = "" [string] Title for the plot. If left blank, the name of the input image, appended with the extname and image section, is used. From 180777a48192d3d7d1df3c0b7d27d287e4e55853 Mon Sep 17 00:00:00 2001 From: Steve Crawford <36652656+stscicrawford@users.noreply.github.com> Date: Wed, 13 Feb 2019 11:01:13 -0500 Subject: [PATCH 8/8] Update pstat.py Address comments from Sara --- wfc3tools/pstat.py | 19 +++++++------------ 1 file changed, 7 insertions(+), 12 deletions(-) diff --git a/wfc3tools/pstat.py b/wfc3tools/pstat.py index 6ebef9f..4fc7b8e 100644 --- a/wfc3tools/pstat.py +++ b/wfc3tools/pstat.py @@ -166,7 +166,7 @@ def pstat(filename, extname="sci", units="counts", stat="midpt", mask=None, for i in range(1, nsamp, 1): data = myfile[extname.upper(), i].data[xstart:xend, ystart:yend] - # mask the data and remove outlyier values + # mask the data and remove outlier values if mask is not None: data = data[~mask[xstart:xend, ystart:yend]] @@ -182,20 +182,15 @@ def pstat(filename, extname="sci", units="counts", stat="midpt", mask=None, if "midpt" in stat: yaxis[i-1] = np.median(data) - - if "mean" in stat: + elif "mean" in stat: yaxis[i-1] = np.mean(data) - - if "mode" in stat: - yaxis[i-1] = mode(data, axis=None)[0] - - if "min" in stat: + elif "mode" in stat: + yaxis[i-1] = mode(data, axis=None)[0]= + elif "min" in stat: yaxis[i-1] = np.min(data) - - if "max" in stat: + elif "max" in stat: yaxis[i-1] = np.max(data) - - if "stddev" in stat: + elif "stddev" in stat: yaxis[i-1] = np.std(data) exptime = myfile["SCI", i].header['SAMPTIME']