a2p2 0.2.14__py3-none-any.whl → 0.7.4__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- a2p2/__main__.py +40 -1
- a2p2/chara/facility.py +54 -4
- a2p2/chara/gui.py +31 -5
- a2p2/client.py +158 -31
- a2p2/facility.py +14 -1
- a2p2/gui.py +46 -12
- a2p2/instrument.py +3 -0
- a2p2/jmmc/__init__.py +7 -0
- a2p2/jmmc/catalogs.py +129 -0
- a2p2/jmmc/generated_models.py +191 -0
- a2p2/jmmc/models.py +104 -0
- a2p2/jmmc/services.py +16 -0
- a2p2/jmmc/utils.py +130 -0
- a2p2/jmmc/webservices.py +48 -0
- a2p2/ob.py +98 -9
- a2p2/samp.py +20 -0
- a2p2/version.py +210 -131
- a2p2/vlti/conf/GRAVITY_ditTable.json +21 -19
- a2p2/vlti/conf/GRAVITY_rangeTable.json +200 -28
- a2p2/vlti/conf/MATISSE_rangeTable.json +58 -22
- a2p2/vlti/conf/PIONIER_ditTable.json +1 -1
- a2p2/vlti/conf/PIONIER_rangeTable.json +16 -18
- a2p2/vlti/facility.py +160 -43
- a2p2/vlti/gravity.py +243 -311
- a2p2/vlti/gui.py +165 -39
- a2p2/vlti/instrument.py +266 -49
- a2p2/vlti/matisse.py +61 -147
- a2p2/vlti/pionier.py +34 -157
- {a2p2-0.2.14.dist-info → a2p2-0.7.4.dist-info}/METADATA +34 -20
- a2p2-0.7.4.dist-info/RECORD +39 -0
- {a2p2-0.2.14.dist-info → a2p2-0.7.4.dist-info}/WHEEL +1 -1
- {a2p2-0.2.14.dist-info → a2p2-0.7.4.dist-info}/entry_points.txt +0 -1
- a2p2/vlti/confP104/GRAVITY_ditTable.json +0 -122
- a2p2/vlti/confP104/GRAVITY_rangeTable.json +0 -202
- a2p2/vlti/confP104/MATISSE_ditTable.json +0 -2
- a2p2/vlti/confP104/MATISSE_rangeTable.json +0 -202
- a2p2/vlti/confP104/PIONIER_ditTable.json +0 -77
- a2p2/vlti/confP104/PIONIER_rangeTable.json +0 -118
- a2p2/vlti/confP105/GRAVITY_ditTable.json +0 -37
- a2p2/vlti/confP105/GRAVITY_rangeTable.json +0 -42
- a2p2/vlti/confP105/MATISSE_ditTable.json +0 -2
- a2p2/vlti/confP105/MATISSE_rangeTable.json +0 -44
- a2p2/vlti/confP105/PIONIER_ditTable.json +0 -25
- a2p2/vlti/confP105/PIONIER_rangeTable.json +0 -38
- a2p2-0.2.14.dist-info/RECORD +0 -44
- {a2p2-0.2.14.dist-info → a2p2-0.7.4.dist-info}/LICENSE +0 -0
- {a2p2-0.2.14.dist-info → a2p2-0.7.4.dist-info}/top_level.txt +0 -0
a2p2/vlti/facility.py
CHANGED
@@ -3,7 +3,12 @@
|
|
3
3
|
__all__ = []
|
4
4
|
|
5
5
|
import os
|
6
|
+
from tkinter.constants import TRUE
|
6
7
|
import traceback
|
8
|
+
import logging
|
9
|
+
import re
|
10
|
+
|
11
|
+
import p2api
|
7
12
|
|
8
13
|
from a2p2.facility import Facility
|
9
14
|
from a2p2.vlti.gui import VltiUI
|
@@ -48,6 +53,7 @@ On your first valid VLTI's OB, A2p2 will ask for your ESO User Portal credential
|
|
48
53
|
"""
|
49
54
|
HELPTEXT += "Config files loaded from " + CONFDIR
|
50
55
|
|
56
|
+
logger = logging.getLogger(__name__)
|
51
57
|
|
52
58
|
class VltiFacility(Facility):
|
53
59
|
|
@@ -77,53 +83,142 @@ class VltiFacility(Facility):
|
|
77
83
|
self.username = None
|
78
84
|
self.api = None
|
79
85
|
|
86
|
+
# store ob to insert after container selection if not done previously
|
87
|
+
self.ob_to_confirm=[]
|
88
|
+
self.ob_to_submit=[]
|
89
|
+
|
90
|
+
|
80
91
|
def getName():
|
81
92
|
return "VLTI"
|
82
93
|
|
83
94
|
def autologin(self):
|
95
|
+
self.ui.addToLog("\nAutologin into P2 API please wait...\n")
|
84
96
|
self.ui.loginFrame.on_loginbutton_clicked()
|
85
97
|
self.a2p2client.ui.showFacilityUI(self.ui)
|
86
98
|
self.ui.showTreeFrame()
|
87
99
|
|
88
100
|
def processOB(self, ob):
|
101
|
+
# process last accepted OB if ob is None
|
102
|
+
if not ob:
|
103
|
+
self.processLastAcceptedOB()
|
104
|
+
return
|
105
|
+
|
89
106
|
# give focus on last updated UI
|
90
107
|
self.a2p2client.ui.showFacilityUI(self.ui)
|
91
108
|
# show ob dict for debug
|
92
109
|
self.ui.addToLog(str(ob), False)
|
93
110
|
|
94
111
|
# OB is checked and submitted by instrument
|
112
|
+
period = ob.getPeriod()
|
113
|
+
self.ui.addToLog(f"Request received for OB creation for P{period} - please press Submit or Abort button")
|
114
|
+
|
115
|
+
# always stores OB and pop them if everything is ok or later selecting containers in the tree
|
116
|
+
self.pushOB(ob)
|
117
|
+
self.tryLastOB()
|
118
|
+
|
119
|
+
def tryLastOB(self):
|
120
|
+
self.showOBConfirmationButtons()
|
121
|
+
# stop if no ob has to be handled
|
122
|
+
if not self.hasOB():
|
123
|
+
return
|
124
|
+
|
125
|
+
ob = self.ob_to_confirm[-1]
|
126
|
+
# run checkOB which may raise some error before connection request
|
127
|
+
# TODO we should test much more because lot of stuff still are beeing processed on live ob creations
|
128
|
+
|
129
|
+
period = ob.getPeriod()
|
95
130
|
instrument = self.getInstrument(ob.instrumentConfiguration.name)
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
#
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
self.
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
131
|
+
insname = instrument.getShortName()
|
132
|
+
|
133
|
+
# performs operation
|
134
|
+
if not self.isConnected():
|
135
|
+
self.ui.showLoginFrame(ob)
|
136
|
+
elif not self.isReadyToSubmit(ob):
|
137
|
+
# self.a2p2client.ui.addToLog("Receive OB for
|
138
|
+
# '"+ob.instrumentConfiguration.name+"'")
|
139
|
+
self.ui.addToLog(
|
140
|
+
f"Selected folder must not be a concatenation. please choose another container for '{insname}' P'{period}'.")
|
141
|
+
elif insname.lower() != self.containerInfo.getInstrument().lower():
|
142
|
+
self.ui.addToLog(
|
143
|
+
f"'{self.containerInfo.getInstrument()}' selection in not applicable for received OB. Please choose another one for '{insname}' P'{period}'.")
|
144
|
+
elif period != int(self.containerInfo.getIpVersion()):
|
145
|
+
self.ui.addToLog(
|
146
|
+
f"Container's IpVersion '{int(self.containerInfo.getIpVersion())}' is not applicable for received OB's one '{period}', please select another '{insname}' container or change it in Aspro2.")
|
147
|
+
else:
|
148
|
+
self.showOBConfirmationButtons(ob, insname=="GRAVITY")
|
149
|
+
|
150
|
+
def showOBConfirmationButtons(self, ob=None, showAcqButtons=False):
|
151
|
+
self.ui.showOBConfirmationButtons(ob, showAcqButtons)
|
152
|
+
|
153
|
+
def isReadyToSubmit(self, ob):
|
154
|
+
return self.api and self.containerInfo.isOk(ob)
|
155
|
+
|
156
|
+
def isConnected(self):
|
157
|
+
return self.connected
|
158
|
+
|
159
|
+
def setConnected(self, flag):
|
160
|
+
self.connected = flag
|
161
|
+
|
162
|
+
def pushOB(self,ob):
|
163
|
+
self.ob_to_confirm.append(ob)
|
164
|
+
|
165
|
+
def hasOB(self):
|
166
|
+
return len(self.ob_to_confirm)>0
|
167
|
+
|
168
|
+
def popOB(self, ignore=False):
|
169
|
+
""" Called as last step : ob is for the selected container and User click on submit!
|
170
|
+
If ignore is set to True, last ob is simply removed else it is forwarded to P2 and removed from stack. """
|
171
|
+
|
172
|
+
if not self.hasOB():
|
173
|
+
return
|
174
|
+
|
175
|
+
# pop last OB
|
176
|
+
o = self.ob_to_confirm.pop()
|
177
|
+
self.showOBConfirmationButtons()
|
117
178
|
|
118
|
-
|
119
|
-
|
179
|
+
if ignore:
|
180
|
+
self.ui.addToLog("Last received OB has been aborted")
|
181
|
+
return
|
182
|
+
else:
|
183
|
+
self.ob_to_submit.append(o)
|
184
|
+
|
185
|
+
def processLastAcceptedOB(self):
|
186
|
+
if len(self.ob_to_submit)==0:
|
187
|
+
return
|
188
|
+
|
189
|
+
o=self.ob_to_submit.pop()
|
190
|
+
try:
|
191
|
+
instrument = self.getInstrument(o.instrumentConfiguration.name)
|
192
|
+
instrument.checkOB(o)
|
193
|
+
# check for warnings and abort if requested by user
|
194
|
+
# this implementation should be more detailled so we can have various VERSION associated to various warning
|
195
|
+
if len(instrument.warnings)>0:
|
196
|
+
linesep="\n - "
|
197
|
+
header=""
|
198
|
+
try:
|
199
|
+
# some ditTable may have a VERSION entry some not...
|
200
|
+
version=instrument.getDitTable()["VERSION"]
|
201
|
+
header= f"According to the template manual {version} :\n \n - \n"
|
202
|
+
except:
|
203
|
+
pass
|
204
|
+
answer = self.ui.AskYesNoMessage(f"{header} {linesep.join(instrument.warnings)}\n\nClick \"Yes\" to proceed \"No\" to abort the submission")
|
205
|
+
instrument.warnings.clear()
|
206
|
+
if answer == False:
|
207
|
+
self.ui.addToLog("Submission has been marked to be aborted - do not proceed")
|
208
|
+
return
|
209
|
+
|
210
|
+
self.ui.addToLog("Everything ready! Request OB creation inside selected container")
|
211
|
+
instrument.submitOB(o, self.containerInfo)
|
212
|
+
|
213
|
+
# TODO add P2Error handling P2Error(r.status_code, method, url,
|
214
|
+
# r.json()['error'])
|
120
215
|
except ValueError as e:
|
121
216
|
traceback.print_exc()
|
122
217
|
trace = traceback.format_exc(limit=1)
|
123
218
|
# ui.ShowErrorMessage("Value error :\n %s \n%s\n\n%s" % (e, trace,
|
124
219
|
# "Aborting submission to P2. Look at the whole traceback in the log."))
|
125
220
|
self.ui.ShowErrorMessage("Value error :\n %s \n\n%s" %
|
126
|
-
|
221
|
+
(e, "Aborting submission to P2. Please check LOG and fix before new submission."))
|
127
222
|
trace = traceback.format_exc()
|
128
223
|
self.ui.addToLog(trace, False)
|
129
224
|
self.ui.setProgress(0)
|
@@ -138,27 +233,23 @@ class VltiFacility(Facility):
|
|
138
233
|
self.ui.addToLog(trace, False)
|
139
234
|
self.ui.setProgress(0)
|
140
235
|
|
141
|
-
def isReadyToSubmit(self):
|
142
|
-
return self.api and self.containerInfo.isOk()
|
143
|
-
|
144
|
-
def isConnected(self):
|
145
|
-
return self.connected
|
146
|
-
|
147
|
-
def setConnected(self, flag):
|
148
|
-
self.connected = flag
|
149
|
-
|
150
236
|
def getStatus(self):
|
237
|
+
ob_info=""
|
238
|
+
if self.hasOB():
|
239
|
+
ob_info=f" / {len(self.ob_to_confirm)} OB in stack"
|
151
240
|
if self.isConnected():
|
152
|
-
return " P2API connected with
|
241
|
+
return f" P2API({self.apitype}) connected with {self.username} { ob_info }"
|
153
242
|
|
154
243
|
def connectAPI(self, username, password, ob):
|
155
|
-
|
156
|
-
if username == TUTORIAL_LOGIN or username == JMMC_LOGIN:
|
244
|
+
if username == TUTORIAL_LOGIN: # or username == JMMC_LOGIN:
|
157
245
|
self.apitype = DEMO_APITYPE
|
158
246
|
else:
|
159
247
|
self.apitype = PRODUCTION_APITYPE
|
160
248
|
try:
|
249
|
+
logger.info("Connecting to p2 api...")
|
161
250
|
self.api = p2api.ApiConnection(self.apitype, username, password)
|
251
|
+
|
252
|
+
self.ui.addToLog("Connected to p2 api (%s)"%self.apitype)
|
162
253
|
# TODO test that api is ok and handle error if any...
|
163
254
|
|
164
255
|
self.refreshTree()
|
@@ -167,9 +258,9 @@ class VltiFacility(Facility):
|
|
167
258
|
self.username = username
|
168
259
|
self.ui.showTreeFrame(ob)
|
169
260
|
except:
|
170
|
-
self.ui.
|
261
|
+
self.ui.ShowErrorMessage("Can't connect to P2 (see LOG).")
|
171
262
|
trace = traceback.format_exc()
|
172
|
-
self.ui.addToLog(trace, False)
|
263
|
+
self.ui.addToLog(trace, False, level=logging.ERROR)
|
173
264
|
|
174
265
|
def refreshTree(self):
|
175
266
|
runs, _ = self.api.getRuns()
|
@@ -190,9 +281,12 @@ class VltiFacility(Facility):
|
|
190
281
|
"""
|
191
282
|
return CONFDIR
|
192
283
|
|
284
|
+
def getIssVltiTypes(self):
|
285
|
+
return ['snapshot','imaging','time-series','astrometry']
|
286
|
+
|
193
287
|
|
194
|
-
# TODO Move code out of this class
|
195
288
|
|
289
|
+
# TODO Move code out of this class
|
196
290
|
|
197
291
|
class P2Container:
|
198
292
|
# run object stores:
|
@@ -216,23 +310,46 @@ class P2Container:
|
|
216
310
|
self.containerId = item['containerId']
|
217
311
|
self.log()
|
218
312
|
|
313
|
+
def reset(self):
|
314
|
+
self.run = None # dict returned by p2api
|
315
|
+
self.containerId = None
|
316
|
+
self.item = None
|
317
|
+
|
219
318
|
def log(self):
|
319
|
+
logmsg = f"*** Working with {self} ***"
|
220
320
|
if self.run != self.item and self.item['itemType'] == ITEMTYPE_CONCATENATION:
|
321
|
+
self.reset()
|
221
322
|
self.facility.ui.addToLog(
|
222
|
-
"*** Please do not select a Concatenation and select another container. ***")
|
323
|
+
"*** Please do not select a Concatenation and select another container. Or just append a calibrator. ***", )
|
324
|
+
logger.info(logmsg)
|
223
325
|
else:
|
224
|
-
self.facility.ui.addToLog(
|
326
|
+
self.facility.ui.addToLog(logmsg)
|
225
327
|
|
226
|
-
def isOk(self):
|
328
|
+
def isOk(self, ob):
|
329
|
+
""" Tell if given container is ready to receive content of given OB."""
|
227
330
|
if self.run == None:
|
228
331
|
return False
|
229
332
|
if self.run == self.item:
|
230
333
|
return True
|
231
|
-
|
334
|
+
|
335
|
+
has_calib = False
|
336
|
+
has_science = False
|
337
|
+
for obsConf in ob.observationConfiguration:
|
338
|
+
if 'SCIENCE' in obsConf.type:
|
339
|
+
has_science = True
|
340
|
+
else:
|
341
|
+
has_calib = True
|
342
|
+
|
343
|
+
if has_science:
|
344
|
+
return self.item['itemType'] != ITEMTYPE_CONCATENATION
|
345
|
+
return has_calib
|
232
346
|
|
233
347
|
def getInstrument(self):
|
234
348
|
return self.run['instrument']
|
235
349
|
|
350
|
+
def getIpVersion(self):
|
351
|
+
return self.run['ipVersion']
|
352
|
+
|
236
353
|
def isRoot(self):
|
237
354
|
return self.item.keys() != None and 'pi' in self.item.keys()
|
238
355
|
|