DTObs.py 7.21 KB
Newer Older
1
2
#!/usr/bin/env python3

marc's avatar
marc committed
3
4
5
6
7
8
import sys
import csv
import logging
from telescope import telescope

from PyQt5 import QtGui
Tammo Jan Dijkema's avatar
Tammo Jan Dijkema committed
9
from PyQt5.QtCore import QRunnable, QObject, pyqtSignal, pyqtSlot, QThreadPool
marc's avatar
marc committed
10
11
from PyQt5.QtWidgets import (QFileDialog, QApplication, QMainWindow, QTableWidgetItem)
from ui.dtobswindow import Ui_mainWindow
12
import subprocess
marc's avatar
marc committed
13
14
import traceback
import time
Tammo Jan Dijkema's avatar
Tammo Jan Dijkema committed
15
import numpy as np
marc's avatar
marc committed
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38

from astropy import units as u
from astropy.coordinates import SkyCoord

class WorkerSignals(QObject):
    """
    Defines the signals available from a running worker thread.

    Supported signals are:

    finished
        `int` of the setpoint number

    error
        `tuple` (exctype, value, traceback.format_exc() )

    result
        `object` data returned from processing, anything

    progress
        `int` inicating % progress
    """

39
40
41
42
    finished = pyqtSignal(int, str)
    allfinished = pyqtSignal()
    # error = pyqtSignal(tuple)
    # result = pyqtSignal(object)
Tammo Jan Dijkema's avatar
Tammo Jan Dijkema committed
43
    progress = pyqtSignal(int, int, str) # meas_num, percent_complete, remaining
marc's avatar
marc committed
44
45
46
47
48
49
50
51
52
53
54
55
56

class Worker(QRunnable):
    """ Execute a function asynchronously, connect to signals """

    def __init__(self, function_to_run, *args, **kwargs):
        super(Worker, self).__init__()
        # Store arguments
        self.function_to_run = function_to_run
        self.args = args
        self.kwargs = kwargs
        self.signals = WorkerSignals()

        self.kwargs['oneSetpointCompleteSignal'] = self.signals.finished
Tammo Jan Dijkema's avatar
Tammo Jan Dijkema committed
57
        self.kwargs['progressSignal'] = self.signals.progress
marc's avatar
marc committed
58
59
60
61
62

    @pyqtSlot()
    def run(self):
        """ Initialize the runner function with passed args, kwargs """

63
64
        self.function_to_run(*self.args, **self.kwargs)
        self.signals.allfinished.emit()
marc's avatar
marc committed
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87

class DTObservationProgram(Ui_mainWindow):
    def __init__(self, mainWindow):
        self.radec = None

        Ui_mainWindow.__init__(self)
        self.setupUi(mainWindow)
        self.actionOpen.triggered.connect(self.openFileNameDialog)
        self.pushButtonStartMeasurement.clicked.connect(self.startMeasurement)
        self.pushButtonStopMeasurement.clicked.connect(self.stopMeasurement)

        self.myDT = telescope(setmode='J2000', consoleHost='consoledemo.dmz.camras.nl')

        self.threadpool = QThreadPool()

    def openFileNameDialog(self):
        '''
        Clear tableWidget and read pointings from file
        '''
        fileName,_ = QFileDialog.getOpenFileName(None, 'Open File', '/home/marc/git/CAMRASTools/DTObs')
        if fileName:
            reader = csv.reader(open(fileName),delimiter='\t')
            rowPosition = self.tableWidgetPointings.rowCount()
88

marc's avatar
marc committed
89
90
91
92
93
94
95
            for meas, ra, dec in reader:
                self.radec = SkyCoord(float(ra)*u.degree, float(dec)*u.degree, frame='icrs')
                (raStr, decStr)  = self.radec.to_string('hmsdms').split()

                self.tableWidgetPointings.insertRow(rowPosition)
                self.tableWidgetPointings.setItem(rowPosition, 0, QTableWidgetItem(raStr))
                self.tableWidgetPointings.setItem(rowPosition, 1, QTableWidgetItem(decStr))
96
97
98
                self.tableWidgetPointings.setItem(rowPosition, 2, QTableWidgetItem(""))

                rowPosition += 1
marc's avatar
marc committed
99
100
101

        self.tableWidgetPointings.resizeColumnsToContents()

102
103
104
105
106
    def allCompleted(self):
        """ Callback function when all pointings completed """
        print("All pointings completed")

    def measCompleted(self, meas_num, status):
marc's avatar
marc committed
107
        """ Make the meas_num-th row of the table green """
108
109
110
        colors = {'Completed': QtGui.QColor('green'),
                  'Slewing'  : QtGui.QColor('yellow'),
                  'Measuring': QtGui.QColor('cyan')}
111
112

        self.tableWidgetPointings.item(meas_num, 2).setText(status)
marc's avatar
marc committed
113
        for column in range(3):
114
            self.tableWidgetPointings.item(meas_num,column).setBackground(colors[status])
marc's avatar
marc committed
115
116
        self.tableWidgetPointings.resizeColumnsToContents()

Tammo Jan Dijkema's avatar
Tammo Jan Dijkema committed
117
    def goToSetpoints(self, setpoints, oneSetpointCompleteSignal=None, progressSignal=None):
marc's avatar
marc committed
118
119
120
        """ Send a list of setpoints to the telescope """
        for setpoint_nr, setpoint in enumerate(setpoints):
            self.myDT.setRaDec(setpoint)
121
            oneSetpointCompleteSignal.emit(setpoint_nr, 'Slewing')
Tammo Jan Dijkema's avatar
Tammo Jan Dijkema committed
122
123
124
125
126
127
128
129
130
131
132
            time.sleep(3)
            dist = np.sqrt(self.myDT.dist_el**2+self.myDT.dist_az**2)
            firstDist = dist
            while not dist < 0.01*u.deg:
                percentSlew = max(100 - dist/firstDist*100, 0)
                progressSignal.emit(setpoint_nr, percentSlew, "{:.3f}°".format(dist.value))
                #print("{:.3f}".format(dist))
                #print("{:2.0f}".format(percentSlew.value))
                self.myDT.getDistance(waitForUpdate=True)
                dist = np.sqrt(self.myDT.dist_el**2+self.myDT.dist_az**2)

133
            oneSetpointCompleteSignal.emit(setpoint_nr, 'Measuring')
Tammo Jan Dijkema's avatar
Tammo Jan Dijkema committed
134
            self.doMeasurement(setpoint_nr, progressSignal=progressSignal)
135
            oneSetpointCompleteSignal.emit(setpoint_nr, 'Completed')
Tammo Jan Dijkema's avatar
Tammo Jan Dijkema committed
136
137
138
139
140
141
142
143
144

    def updateProgress(self, meas_num, progress_percent, remaining_str):
        """
        Update the table with some progress indicator

        meas_num: the row which needs to be updated
        progress_percent: integer giving the percentage complete
        remaining_str: string indicating how much remaining, e.g. "1:30" or "3°"
        """
145
146
        #self.tableWidgetPointings.item(meas_num, 2).setText(remaining_str)
        self.tableWidgetPointings.item(meas_num, 2).setText(str(progress_percent)+"%")
Tammo Jan Dijkema's avatar
Tammo Jan Dijkema committed
147
148
149


    def doMeasurement(self, measnum, progressSignal=None):
150
151
        """ Dumping data into file including meta-data"""
        print("start dump-wide")
Tammo Jan Dijkema's avatar
Tammo Jan Dijkema committed
152
153
154
155
156
157
158
159
160
161
        integrationTime = self.spinBoxIntTime.value()
        #self.measprog = subprocess.Popen(["cat","/home_local/camrasdemo/test-001.txt"], stdout=subprocess.PIPE)
        self.measprog = subprocess.Popen(["sleep", str(integrationTime)], stdout=subprocess.PIPE)
        for sec in range(integrationTime):
            remainstring =  str(int((integrationTime-sec)/60)) + ":"
            remainstring += "{:02}".format((integrationTime-sec)%60)
            progressSignal.emit(measnum, int(float(sec)/integrationTime*100), remainstring)
            time.sleep(1)
        self.measprog.wait()
        data = self.measprog.stdout
marc's avatar
marc committed
162
163
164
165
166

    def startMeasurement(self):
        print("Measurement started")
        setpoints = []
        for meas in range(0,self.tableWidgetPointings.rowCount()):
167
            ra  = self.tableWidgetPointings.item(meas, 0).text()
marc's avatar
marc committed
168
169
            dec = self.tableWidgetPointings.item(meas, 1).text()

170
            self.tableWidgetPointings.item(meas, 2).setText("Scheduled")
marc's avatar
marc committed
171
172
173
174
175
176
            self.tableWidgetPointings.resizeColumnsToContents()
            setpoint = SkyCoord(ra, dec, frame='icrs')
            setpoints.append(setpoint)

        worker = Worker(self.goToSetpoints, setpoints)
        worker.signals.finished.connect(self.measCompleted)
177
        worker.signals.allfinished.connect(self.allCompleted)
Tammo Jan Dijkema's avatar
Tammo Jan Dijkema committed
178
        worker.signals.progress.connect(self.updateProgress)
marc's avatar
marc committed
179
180
181
182
183
184
185
186
187
188
189
190
191
192
        self.threadpool.start(worker)

    def stopMeasurement(self):
        print("Measurement stopped")

if __name__ == '__main__':
    app = QApplication(sys.argv)
    mainWindow = QMainWindow()

    prog = DTObservationProgram(mainWindow)

    mainWindow.show()
    sys.exit(app.exec_())

Tammo Jan Dijkema's avatar
Tammo Jan Dijkema committed
193