#!/bin/env python # TODO - change USNO processing to check if schedule only contains MK and PT antennas from sys import argv, exit, stdin from os import system, chdir, getcwd, environ, popen from os.path import isfile, isdir from string import replace, strip, split, lower, upper, find import datetime program = 'unqueueVex' version = 0.2 verdate = '20111214' author = 'Walter Brisken' verbose = 1 observTxFile = 'observ.tx' ccScriptDir = '/export/home/cc/vlba/scripts' prestartTime = 300 # seconds poststopTime = 30 # seconds difxPath = '/home/swc/DiFX-trunk/bin' difxbinpath = '/users/difx/bin' linesToShow = 10 # ------------------ def usage(): print '\n%s ver. %s %s %s\n' % (program, version, verdate, author) print 'Usage: %s [options] [vexfile2] ... [ant1] [ant2] ...\n' % argv[0] print 'options can be:\n' print ' -h or --help print help info and quit.' print ' -v or --verbose make more verbose.' print ' -q or --quiet make less verbose.' print ' -f or --force proceed without question in some cases.' print '' print 'One or more vex files can be supplied. All supplied vex files will' print 'be handled separately in the order listed.' print '' print 'Optional list of antenna codes can be used to restrict which antennas' print 'to operate on. If no antennas are listed, all antennas in the vex' print 'file(s) will be assumed.' mjd0 = datetime.datetime(1858, 11, 17, 0, 0) def execute(cmd, nostdout=0): if verbose > 0: print 'About to execute: %s' % cmd if nostdout == 0: system(cmd) else: popen(cmd).readlines() def vexPeek(vexFile): cmd = '%s/vexpeek %s' % (difxPath, vexFile) if verbose > 0: print 'Executing command: %s' % cmd p = popen(cmd) data = p.readlines() if len(data) == 0: return 'Error', 'Error', 'Error' obsCode = upper(strip(data[0])) obsSeg = '' if obsCode[0:5] == 'ERROR': return 'Error', 'Error', 'Error' if len(obsCode) > 3: if obsCode[0].isalpha() and obsCode[1].isalpha() and obsCode[2].isdigit(): for i in range(3, len(obsCode)): if obsCode[i].isalpha(): obsSeg = obsCode[i:] obsCode = obsCode[0:i] break if obsCode[0].isalpha() and obsCode[1].isdigit(): for i in range(2, len(obsCode)): if obsCode[i].isalpha(): obsSeg = obsCode[i:] obsCode = obsCode[0:i] break stationTimes = {} for d in data[1:]: s = split(strip(d)) stationTimes[upper(s[0])] = [float(s[1])-prestartTime/86400.0, float(s[2])+poststopTime/86400.0] print 'This is experiment %s %s' % (obsCode, obsSeg) return obsCode, obsSeg, stationTimes def mjd2datetime(mjd): mon = ['JAN', 'FEB', 'MAR', 'APR', 'MAY', 'JUN', 'JUL', 'AUG', 'SEP', 'OCT', 'NOV', 'DEC'] dt = datetime.timedelta(int(mjd), int((mjd - int(mjd))*86400.0 + 0.5)) t = mjd0 + dt return '%04d%s%02d %02dh%02dm%02ds' % (t.year, mon[t.month-1], t.day, t.hour, t.minute, t.second) # take string date (d) and time (t), as formatted above, and return MJD def vlba2mjd(d, t): monnames = ['JAN', 'FEB', 'MAR', 'APR', 'MAY', 'JUN', 'JUL', 'AUG', 'SEP', 'OCT', 'NOV', 'DEC'] yr = int(d[0:4]) monname = d[4:7] mn = 0 for m in range(len(monnames)): if monname == monnames[m]: mn = m+1 da = int(d[7:9]) hr = int(t[0:2]) mi = int(t[3:5]) se = int(t[6:8]) mjd = (datetime.datetime(yr, mn, da, 0, 0) - mjd0).days + hr/24.0 + mi/1440.0 + se/86400.0 return mjd def sortmetric(x): y = split(x) return vlba2mjd(y[1], y[2]) def rmObservation(orig, expt, station): observations = [] for o in orig: # calc time # keep only obs from last 7 days and beyond v = split(strip(o), '>') s = split(v[0]) if len(s) < 5 or len(v) < 2: observations.append(o) continue expt0 = s[0] if expt0 == expt: continue # don't keep old entry observations.append(o) # sort by start time observations.sort(key=sortmetric) # glue: if removed observation was between two copies of same # experiment, assume it was interrupted by the observation that # was removed, so put them back together index = 0 while len(observations) > index+1: v1 = split(observations[index], '>') s1 = split(v1[0]) v2 = split(observations[index+1], '>') s2 = split(v2[0]) if s1[0] == s2[0] and v1[1] == v2[1]: # copy end date,time from second expt to first observations[index] = '%s %s %s %s %s > %s' % (s1[0], s1[1], s1[2], s2[3], s2[4], v1[1]) observations.pop(index+1) else: index += 1 return observations # ----------------- VLBAStations = ['br', 'fd', 'hn', 'kp', 'la', 'mk', 'nl', 'ov', 'pt', 'sc'] vexFiles = [] antennas = [] force = False for a in argv[1:]: if a[0] == '-': if a in ['-h', '--help']: usage() exit(1) elif a in ['-v', '--verbose']: verbose += 1 elif a in ['-q', '--quiet']: verbose -= 1 elif a in ['-f', '--force']: force = True else: print 'Unknown option "%s"\n' % a exit(1) elif len(a) > 3: vexFiles.append(a) else: antennas.append(a) if len(vexFiles) == 0: usage() exit(0) if len(vexFiles) > 1: print 'The following vex files will be unqueued:' for vexFile in vexFiles: print ' %s' % vexFile if not force: print 'If this is not what you intend, use ^C now to stop.' print 'Otherwise press Enter to continue.' stdin.readline() cwd = getcwd() if find(upper(cwd), 'MARK5C') < 0: if isdir(cwd+'/MARK5C') > 0: if not force: print '\nWarning: %s/MARK5C is presumably where you want to run this.' % cwd print 'Try again with -f to force the operation' else: print '\nContinuing because of -f (or --force) even though %s/MARK5C' % cwd print 'seems more likely to be where you want to run this.' elif isdir(cwd+'/../MARK5C') > 0: if not force: print '\nWarning: %s/../MARK5C is presumably where you want to run this.' % cwd print 'Try again with -f to force the operation' else: print '\nContinuing because of -f (or --force) even though %s/MARK5C' % cwd print 'seems more likely to be where you want to run this.' else: print '\nYou are running %s from a non-Mark5C directory.' % program print 'I hope this is what you want!\n' for vexFile in vexFiles: if not isfile(vexFile): print 'Error: cannot find file %s' % vexFile exit(0) for vexFile in vexFiles: if vexFile[0] != '/': vexFile = '%s/%s' % (cwd, vexFile) obsCode, obsSeg, stationTimes = vexPeek(vexFile) scripts = [] for s in stationTimes: scriptName = upper(obsCode+obsSeg+'.'+s)+'.py' scripts.append(scriptName) scripts.sort() print 'scripts=', scripts chdir('/tmp') for script in scripts: s = split(script, '.') station = lower(s[-2]) if len(antennas) > 0 and not station in antennas: print '** Skipping antenna %s from vex file %s' % (upper(station), vexFile) continue if not station in VLBAStations: print '** Non-VLBA station %s being skipped' % upper(station) continue expt = upper(s[0]) print '\n===========================================================================' if station == 'gb': cc = 'gb-cc.gb.nrao.edu' continue # GB not yet handled per the request of GB staff else: cc = '%s-cc.vlba.nrao.edu' % station upperStation = upper(station) timeRange = stationTimes[upperStation] startDate = mjd2datetime(timeRange[0]) stopDate = mjd2datetime(timeRange[1]) print 'STATION %s : was to observe %s from %s to %s' % (upperStation, expt, startDate, stopDate) print '===========================================================================\n' print 'Removing %s from %s' % (script, cc) execute('scp vlbamon@%s:%s/%s . 2>&1' % (cc, ccScriptDir, observTxFile), 0) if not isfile(observTxFile): execute('touch %s' % observTxFile) observations = open(observTxFile).readlines() observations = rmObservation(observations, expt, station) f = open(observTxFile, 'w') for o in observations: f.write(o) f.close() print 'New contents of %s at %s: (only last %d lines shown)' % (observTxFile, upperStation, linesToShow) system('tail -n %d %s' % (linesToShow, observTxFile)) print '' execute('ssh vlbamon@%s rm -f %s/%s 2>&1' % (cc, ccScriptDir, script), 0) execute('scp %s vlbamon@%s:%s 2>&1' % (observTxFile, cc, ccScriptDir), 0) chdir(cwd)