-
Notifications
You must be signed in to change notification settings - Fork 0
/
SNR_GUI_001.py
232 lines (162 loc) · 7.37 KB
/
SNR_GUI_001.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
#########################################
#
# A test UI for SNR plot
# Simple plot for stack images, error images, SNR image and pure spectra
# Version: 0.01 created on 04-Nov-2019, first created by Anika Beer & Joseph, modified by Man I
#
#
# Required Packages:
# Pyqtgraph
# PyParadise
#
#
##########################################
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
from PyQt5.QtCore import *
import pyqtgraph as pg
import numpy as np
import argparse
import pylab
import sys
import os
from PyAstronomy import pyasl
import numpy as np
from astropy.io import fits
class SNR_GUI(QWidget):
# load definition
def __init__(self):
super().__init__()
parser = argparse.ArgumentParser()
parser.add_argument('Directory', help = 'Location of files')
parser.add_argument('GalaxyName', help = 'Name of the galaxy as in file to be used, no path is required')
args = parser.parse_args()
self.path = args.Directory
self.pre = args.GalaxyName
self.initUI()
def initUI(self):
pg.setConfigOption( 'background', 'w')
pg.setConfigOption( 'foreground', 'k')
app = pg.mkQApp()
# set windows
self.window = pg.GraphicsWindow(title='TEST Data SNR Interface')
self.window.resize(1200,1000)
#Load paradise data, variables
self.paradise_data()
# set first image
self.p1 = self.window.addPlot(title='FLUX')
self.image1 = pg.ImageItem()
self.image1.setImage(image = self.stackflux())
self.p1.addItem(self.image1, row=0, col=0)
self.p1.setMenuEnabled(enableMenu=False)
# set first image control bar
hist1 = pg.HistogramLUTItem(fillHistogram=False)
hist1.setImageItem(self.image1)
hist1.setLevels(-1,5)
hist1.setHistogramRange(-1,5)
self.window.addItem(hist1,row=0,col=1)
# set second image
self.p2 = self.window.addPlot(title='SNR')
self.image2 = pg.ImageItem()
self.image2.setImage(image = self.SNR_data())
self.p2.addItem(self.image2, row=0, col=2)
self.p2.setMenuEnabled(enableMenu=False)
# set second image control bar
hist2 = pg.HistogramLUTItem(fillHistogram=False)
hist2.setImageItem(self.image2)
hist2.setLevels(3,10)
hist2.setHistogramRange(3,10)
self.window.addItem(hist2,row=0,col=3)
# set third plot
self.p3 = self.window.addPlot(title='Input', row=1, col=0, colspan=3)
self.p3.plot(self.cube._wave, self.cube._data[:, self.x_mid, self.y_mid]/np.median(self.cube._data[:, self.x_mid, self.y_mid]), pen=(0,0,0), name='Input')
self.p3.setXRange(min(self.cube._wave), max(self.cube._wave))
self.p3.setYRange(-1.0, 2.0)
self.textposx = 0
self.textposy = 0
#cross hair and text
self.text = pg.TextItem(anchor=(0,1),color=(255,153,51))
self.p1.addItem(self.text)
self.vLine = pg.InfiniteLine(angle=90, movable=False, pen=(255,153,51))
self.hLine = pg.InfiniteLine(angle=0, movable=False, pen=(255,153,51))
self.p1.addItem(self.vLine, ignoreBounds=True)
self.p1.addItem(self.hLine, ignoreBounds=True)
self.vb = self.p1.vb
# executions
self.proxy = pg.SignalProxy(self.p1.scene().sigMouseMoved, rateLimit=120, slot=self.mouseMoved)
self.image1.mouseClickEvent = self.mouseClickImg
# load data
# Open data format which suitable for PyParadise
# Not the original cube
def paradise_data(self):
self.cube = fits.open(self.path + self.pre + '.fit')
self.cube._data = self.cube[0].data
self.cube._wave = self.cube[0].header['CRVAL3'] + np.arange(self.cube[0].header['NAXIS3']) * self.cube[0].header['CDELT3']
(self.z,self.y,self.x) = self.cube._data.shape
self.x_mid = self.x//2
self.y_mid = self.y//2
def stackflux(self):
#Use white background and black foreground
# Enable antialiasing
pg.setConfigOptions(antialias=True)
self.map=[]
for xvar in range(self.x):
for yvar in range(self.y):
if self.cube._data[300, yvar, xvar] !=0:
snrEsti = sum(self.cube._data[:,yvar,xvar])/1e5
self.map.append(snrEsti)
else:
self.map.append(0)
self.imagesum = np.array(self.map).reshape(self.x,self.y)
return self.imagesum
# calculate SNR from PyAstronomy
def SNR_data(self):
#Use white background and black foreground
# Enable antialiasing
pg.setConfigOptions(antialias=True)
self.snr=[]
for xvar in range(self.x):
for yvar in range(self.y):
if self.cube._data[300, yvar, xvar] !=0:
snrEsti = np.median(self.cube._data[1500:2000,yvar,xvar])/np.std(self.cube._data[1500:2000,yvar,xvar])
self.snr.append(snrEsti)
else:
self.snr.append(0)
self.imageData = np.array(self.snr).reshape(self.x,self.y)
return self.imageData
def mouseMoved(self, evt):
pos = evt[0] ## using signal proxy turns original arguments into a tuple
if self.p1.sceneBoundingRect().contains(pos):
mousePoint = self.p1.vb.mapSceneToView(pos)
indexx = int(np.floor(mousePoint.x()))
indexy = int(np.floor(mousePoint.y()))
if (indexx >= 0 and indexx <= self.x) and (indexy >= 0 and indexy <= self.y):
self.text.setText("x=%1.0f, y=%1.0f, SNR=%0.01f" % (indexx,indexy,self.imageData[indexx,indexy]))
self.textposx = mousePoint.x()
self.textposy = mousePoint.y()
if (indexx > self.x_mid): #and indexx < (len(imageData)+len(imageData)*0.3)):
self.textposx = mousePoint.x() - int(self.x * 0.4)
if (indexy > self.y - self.y * .1):
self.textposy = mousePoint.y()-int(self.y * 0.1)
self.text.setPos(self.textposx,self.textposy)
self.vLine.setPos(mousePoint.x())
self.hLine.setPos(mousePoint.y())
def mouseClickImg(self, event):
pos_add = event.pos() # position of the mouse
self.pixelx = int(np.floor(pos_add[int(0)]))
self.pixely = int(np.floor(pos_add[int(1)]))
self.p3.clear()
#Add new data
self.p3.setYRange(np.amin(self.cube._data[:, self.pixely, self.pixelx]), np.amax(self.cube._data[:, self.pixely, self.pixelx]))
self.p3.plot(self.cube._wave, self.cube._data[:, self.pixely, self.pixelx], pen=(0,0,0), name="Input")
# Start Qt event loop unless running in interactive mode or using pyside
if __name__ == '__main__':
#Select instance of QApplication
if not QApplication.instance():
app = QApplication(sys.argv)
else:
app = QApplication.instance()
#Run the GUI if being run in interactive mode
if (sys.flags.interactive != 1) or not hasattr(QtCore, 'PYQT_VERSION'):
ex = SNR_GUI()
sys.exit(app.exec_())