This is a python module providing communication abstractions for the OpenScience Observatories telescope.org service. The telescope control is provided through the `Telescope` class which provides state tracking and low level methods - forming a basic API layer. The higher level functions are implemented as separate functions construced with the Telescope class API.

Telescope class

This class orginizes all interaction with the service. It keeps all state and provides higher level functions like login or get_user_requests.

class Telescope[source]

Telescope(user, passwd, cache='.cache/jobs')

cleanup[source]

cleanup(s)

assert cleanup('|ążźćńłóęśĄŻŹĆŃŁÓĘŚ|') == '||'

Telescope.login[source]

Telescope.login()

Telescope.logout[source]

Telescope.logout()

config = configparser.ConfigParser()
config.read(expanduser('~/.config/telescope.ini'))
['/home/jochym/.config/telescope.ini']
OSO=Telescope(config['telescope.org']['user'], 
              config['telescope.org']['password'])

Telescope.get_user_requests[source]

Telescope.get_user_requests(sort='rid', folder=1)

Get all user requests from folder (Inbox=1 by default), sorted by sort column ('rid' by default). Possible sort columns are: 'rid', 'object', 'completion' The data is returned as a list of dictionaries.

reqlst=OSO.get_user_requests(sort='completion')
print(f'Number of users requests: {len(reqlst)}')
reqlst[0]
Number of users requests: 1189
{'id': '725917',
 'seen': '0',
 'usercomments': '',
 'objecttype': 'RADEC',
 'objectid': '18:55:02.31 -31:09:49.59',
 'objectname': 'V1223 Sgr',
 'requesttime': '1630285858',
 'status': '3',
 'row': '1'}

Telescope.get_request[source]

Telescope.get_request(rid=None)

Get request data for a given RID

Telescope.get_user_folders[source]

Telescope.get_user_folders()

Get all user folders. Returns list of dictionaries.

OSO.get_user_folders()
[{'id': '1', 'creationtime': '0', 'name': 'Inbox', 'count': '1189'},
 {'id': '2', 'creationtime': '0', 'name': 'Favourites', 'count': None},
 {'id': '3', 'creationtime': '0', 'name': 'Archive', 'count': '447'},
 {'id': '4', 'creationtime': '0', 'name': 'Trash', 'count': '52'},
 {'id': '461',
  'creationtime': '1407254495',
  'name': 'Complete',
  'count': '13'}]

Telescope.get_obs_list[source]

Telescope.get_obs_list(t=None, dt=1, filtertype='', camera='', hour=16, minute=0)

Get the dt days of observations taken no later then time in t.

Input

t - end time in seconds from the epoch (as returned by time.time()) dt - number of days, default to 1 filtertype - filter by type of filter used camera - filter by the camera/telescope used

Output

Returns a list of JobIDs (int) for the observations.

import datetime

olst = OSO.get_obs_list(t=datetime.datetime(2020, 12, 24).timestamp())
print(f'Observations: {len(olst)}')
Observations: 54

Telescope.get_job[source]

Telescope.get_job(jid=None)

Get a job data for a given JID

for rq in sorted(reqlst, key=lambda r: int(r['requesttime']), reverse=True):
    if Telescope.REQUESTSTATUS_TEXTS[int(rq['status'])]=='Complete':
        break
print(rq)
print(OSO.get_request(int(rq['id'])))
last_complete = int(OSO.get_request(int(rq['id']))['jid'][1:])
{'id': '725587', 'seen': '1', 'usercomments': 'Mira', 'objecttype': 'RADEC', 'objectid': '21:42:42.80 +43:35:09.86', 'objectname': 'SS Cyg', 'requesttime': '1629985062', 'status': '8', 'row': '10'}
{'rid': 725587, 'jid': 'J383646', 'type': 'RADEC', 'oid': '21:42:42.80 +43:35:09.86', 'name': 'SS Cyg', 'exp': '180000 ms', 'filter': 'BVR', 'dark': 'Instant', 'tele_type': 'Galaxy', 'tele': 'COAST', 'requested': ['26', 'August', '2021', '13:37:42', 'UTC'], 'completion': ['30', 'August', '2021', '05:36:05', 'UTC'], 'status': 'Complete', 'flatid': 26}

Basic API calls

User-API

Request Manager

Request Constructor

Telescope.do_api_call[source]

Telescope.do_api_call(module, req, params=None)

obs = OSO.get_job(last_complete)
rsp = OSO.do_api_call("image-engine", "0-create-dlzip", {'jid': obs['jid'], 'flatid': obs['flatid']})
print(rsp)
rsp = OSO.do_api_call("image-engine", "0-is-job-ready", {'ieid':rsp['data']['ieID'],})
print(rsp)
{'success': 1, 'status': 'OK_WAIT', 'data': {'ieID': '1550061'}}
{'success': 1, 'status': 'PROCESSING', 'data': None}

Telescope.do_rm_api[source]

Telescope.do_rm_api(req, params=None)

Telescope.do_rc_api[source]

Telescope.do_rc_api(req, params=None)

Telescope.download_obs[source]

Telescope.download_obs(obs=None, directory='.', cube=True, verbose=False)

Download the raw observation obs (obtained from get_job) into zip file named job_jid.zip located in the directory (current by default). Alternatively, when the cube=True the file will be a 3D fits file. The name of the file (without directory) is returned.

fn = OSO.download_obs(OSO.get_job(last_complete), directory='/tmp', cube=False, verbose=True)
if fn is not None:
    print(f'Removing downloaded file: {fn}')
    os.unlink(os.path.join('/tmp', fn))
else:
    print('Download failed')
OK_WAIT                       
WAIT                          
WAIT                          
WAIT                          
WAIT                          
WAIT                          
READY                         
Removing downloaded file: 383646.zip
fn = OSO.download_obs(OSO.get_job(last_complete), directory='/tmp', cube=True, verbose=True)
if fn is not None:
    print(f'Removing downloaded file: {fn}')
    os.unlink(os.path.join('/tmp', fn))
else:
    print('Download failed')
OK_WAIT                       
PROCESSING                    
PROCESSING                    
READY                         
Removing downloaded file: 383646.fits

Telescope.get_obs[source]

Telescope.get_obs(obs=None, cube=True, recurse=True, verbose=False)

Get the raw observation obs (obtained from get_job) into zip file-like object. The function returns ZipFile structure of the downloaded data.

(OSO.get_obs(OSO.get_job(last_complete), cube=False, verbose=True), 
OSO.get_obs(OSO.get_job(last_complete), cube=True, verbose=True),)
(<zipfile.ZipFile file=<_io.BufferedReader name='.cache/jobs/3/8/383646.zip'> mode='r'>,
 <_io.BufferedReader name='.cache/jobs/3/8/383646.fits'>)

Job submission methods

Submission API

Telescope.submit_job_api[source]

Telescope.submit_job_api(obj, exposure=30000, tele='COAST', filt='BVR', darkframe=True, name='RaDec object', comment='AutoSubmit')

RADEC job submission

Telescope.submit_RADEC_job[source]

Telescope.submit_RADEC_job(obj, exposure=30000, tele='COAST', filt='BVR', darkframe=True, name='RaDec object', comment='AutoSubmit')

Typical variable star job submission

Telescope.submitVarStar[source]

Telescope.submitVarStar(name, expos=90, filt='BVR', comm='', tele='COAST')

if False :
    print("Submitting a VS job")
    rq = OSO.submitVarStar('V1223 Sgr', expos=180)
    if rq[0] :
        print("Waiting for job to be accepted")
        while (status:=OSO.get_request(int(rq[1]))['status'])!='Waiting' :
            print(status, end='\r')
            sys.stdout.flush()
            time.sleep(15)
        print(status)
        print("Cancelling the job")
        OSO.do_rm_api("0-cancel-request", {'rid':int(rq[1])})
        print("Waiting for job to be cancelled")
        while 'pending cancel' in (status:=OSO.get_request(int(rq[1]))['status']):
            print(status, end='\r')
            sys.stdout.flush()
            time.sleep(15)
        print(status)
    else :
        print('Submission failed')
reqlst=OSO.get_user_requests(sort='completion')
for rq in sorted(reqlst, key=lambda r: int(r['requesttime']), reverse=True)[:20]:
    print(f"{rq['objectname']:12}", 
          f"{datetime.datetime.fromtimestamp(int(rq['requesttime']))}",
          f"{rq['id']:12}",
          f"{Telescope.REQUESTSTATUS_TEXTS[int(rq['status'])]}"
         )
V1223 Sgr    2021-08-30 03:10:58 725917       Waiting
V1223 Sgr    2021-08-29 19:13:52 725886       Cancelled
V1223 Sgr    2021-08-28 18:43:05 725790       Cancelled
V1223 Sgr    2021-08-28 18:11:15 725783       Cancelled
V1223 Sgr    2021-08-28 18:03:06 725781       Cancelled
V1223 Sgr    2021-08-28 17:51:38 725780       Cancelled
V1223 Sgr    2021-08-28 14:51:45 725762       Cancelled
EQ Lyr       2021-08-26 15:37:56 725595       Waiting
DQ Vul       2021-08-26 15:37:54 725594       Waiting
DX Vul       2021-08-26 15:37:52 725593       Waiting
BI Her       2021-08-26 15:37:51 725592       Waiting
AS Lac       2021-08-26 15:37:49 725591       Waiting
V686 Cyg     2021-08-26 15:37:47 725590       Waiting
IP Cyg       2021-08-26 15:37:46 725589       Waiting
EU Cyg       2021-08-26 15:37:44 725588       Cancelled
SS Cyg       2021-08-26 15:37:42 725587       Complete
CH Cyg       2021-08-26 15:37:41 725586       Waiting
BI Her       2021-08-18 21:34:34 724987       Complete
EQ Lyr       2021-08-18 21:34:04 724986       Complete
DQ Vul       2021-08-18 21:33:35 724985       Complete
OSO.logout()
from nbdev.export import notebook2script; notebook2script()
Converted 00_core.ipynb.
Converted 01_solver.ipynb.
Converted 02_process.ipynb.
Converted index.ipynb.