#!/bin/env python3 #************************************************************************** # Copyright (C) 2009-2019 by Walter Brisken * # * # This program is free software; you can redistribute it and/or modify * # it under the terms of the GNU General Public License as published by * # the Free Software Foundation; either version 3 of the License, or * # (at your option) any later version. * # * # This program is distributed in the hope that it will be useful, * # but WITHOUT ANY WARRANTY; without even the implied warranty of * # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * # GNU General Public License for more details. * # * # You should have received a copy of the GNU General Public License * # along with this program; if not, write to the * # Free Software Foundation, Inc., * # 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * #************************************************************************** #=========================================================================== # SVN properties (DO NOT CHANGE) # # $Id: oms2v2d 9157 2019-09-16 20:04:36Z WalterBrisken $ # $HeadURL: $ # $LastChangedRevision: 9157 $ # $Author: WalterBrisken $ # $LastChangedDate: 2019-09-16 14:04:36 -0600 (Mon, 16 Sep 2019) $ # #============================================================================ # Note: this utility can run under python2.7 or python3 from sys import argv, exit from os import popen, environ from os.path import isfile, isdir from glob import glob program = 'showcal' version = '0.2' verdate = '20191001' author = 'Walter Brisken' def usage(pgm): print('%s ver. %s %s %s\n' % (program, version, author, verdate)) print('Usage: %s [options] []\n' % pgm) print('\noptions can include:\n') print(' -h or --help print this help information and quit') print('\n is the vex file associated with the project') print('\n is the correlator pass name (.v2d file previx)') print('\n\nThere are two modes of operation. In the first, only a') print('vex file is provided. In this case this program cannot look') print('into the DiFX output directories where pulse cal or Tsys data') print('may be found. Without the information about the correlator') print('setup, this mode cannot determine which antennas were actually') print('to be correlated. In the second mode, the correlator pass is') print('also specified so the DiFX output can be found. Note that') print('in this mode only antennas specified for correlation are') print('listed. It is most useful to run this mode only after') print('correlation has completed.\n') # return project, [ants] # all lowercase def parseVex(vexFile): cmd = 'vexpeek %s' % vexFile data = popen(cmd).readlines() if len(data) == 0: return None project = data[0].strip().lower() if project == 'error': return None ants = [] for d in data[1:]: s = d.strip().split() ants.append(s[0].lower()) return project, ants def fileHasAntenna(file, antenna): if not isfile(file): return False data = open(file).readlines() for d in data: s = d.split() if s[0].lower() == antenna: return True return False def getFlag(project, antenna): flag = '' if fileHasAntenna('%s.%s.flag' % (project, antenna), antenna): flag = flag + 'F' if fileHasAntenna('flag', antenna): flag = flag + 'f' return flag def getTsys(project, antenna): if fileHasAntenna('%s.%s.tsys' % (project, antenna), antenna): return 'T' elif fileHasAntenna('tsys', antenna): return 't' return '' def getWeather(project, antenna): if fileHasAntenna('%s.%s.weather' % (project, antenna), antenna): return 'W' elif fileHasAntenna('weather', antenna): return 'w' return '' def getGain(project, antenna, gainPath): if isfile('%s.%s.gain' % (project, antenna)): return 'G' elif gainPath == '': return '' elif antenna in ['br', 'fd', 'hn', 'kp', 'la', 'mk', 'nl', 'ov', 'pt', 'sc'] and isfile(gainPath + '/vlba_gains.key'): return 'g' elif isfile('%s/gain.%s' % (gainPath, antenna)): return 'g' else: return '' def getPcal(project, antenna): if fileHasAntenna('%s.%s.pcal' % (project, antenna), antenna): return 'P' elif fileHasAntenna('pcal', antenna): return 'p' return '' def getCableCal(project, antenna): # FIXME: look for DiFX-based if fileHasAntenna('%s.%s.cablecal' % (project, antenna), antenna): return 'C' elif fileHasAntenna('%s.%s.pcal' % (project, antenna), antenna): return 'P' elif fileHasAntenna('pcal', antenna): return 'p' return '' def getDiFX(project, antenna, passName, queuePath, type): v = 'X' joblistFile = '%s.joblist' % passName if not isfile(joblistFile): print('\nError: %s not found! Must stop.\n' % joblistFile) exit(0) data = open(joblistFile).readlines() if len(data) < 2: print('\nError: %s has no jobs listed! Must stop.\n' % joblistFile) exit(0) for d in data[1:]: s = d.split('#') if len(s) == 2: if antenna.upper() in s[1]: v = '' # here we have found a job with the antenna in question job = d.split()[0] # first look locally dd = '%s.difx' % job if not isdir(dd) and queuePath != None: # then look in queue dd = '%s/%s/%s.difx' % (queuePath, project.upper(), job) if isdir(dd): g = glob('%s/%s*%s' % (dd, type, antenna.upper())) if len(g) > 0: return 'D' return v vexFile = None passName = None for a in argv[1:]: if a[0] == '-': if a in ['--help', '-h']: usage(argv[0]) exit(0) else: print('Unknown option: %s' % a) exit(0) else: if vexFile == None: vexFile = a elif passName == None: passName = a else: print('Error: unexpected parameter: %s' % a) exit(0) if vexFile == None: print('Error: need to provide vex filename') exit(0) project, ants = parseVex(vexFile) if not 'GAIN_CURVE_PATH' in environ: print('Warning: Env. var. GAIN_CURVE_PATH needs to be defined for gain curves to be found.') gainPath = '' else: gainPath = environ['GAIN_CURVE_PATH'] if not isdir(gainPath): print('Warning: $GAIN_CURVE_PATH is not a directory!') gainPath = '' if 'DIFX_QUEUE_BASE' in environ(): queuePath = environ['DIFX_QUEUE_BASE'] else: if passName != None: print('Error: Env. var. DIFX_QUEUE_BASE is required when a pass name is provided.') exit(0) queuePath = '' # a list of file types that have been found to date codes = '' print('\nProject: %s\n' % project.upper()) print('Ant Flag Tsys Weather Gain Pcal Cablecal') print('--- ---- ---- ------- ---- ---- --------') for a in ants: f = getFlag(project, a) w = getWeather(project, a) if passName != None: t = getDiFX(project, a, passName, queuePath, 'SWITCHEDPOWER') p = getDiFX(project, a, passName, queuePath, 'PCAL') else: t = '' p = '' if t == '': t = getTsys(project, a) g = getGain(project, a, gainPath) if p == '': p = getPcal(project, a) c = getCableCal(project, a) if p == 'X' or t == 'X': continue print('%-8s%-8s%-8s%-8s%-8s%-8s%-8s' % (a.upper(), f, t, w, g, p, c)) codes = codes + f + t + w + g + p + c print('\nSources of data are as follows:') if 'F' in codes: print(' F = %s..flag' % project) if 'f' in codes: print(' f = flag') if 'T' in codes: print(' T = %s..tsys' % project) if 't' in codes: print(' t = tsys') if 'W' in codes: print(' W = %s..weather' % project) if 'w' in codes: print(' w = weather') if 'G' in codes: print(' G = %s..gain' % project) if 'g' in codes: print(' g = $GAIN_CURVE_PATH/ = %s/' % gainPath) if 'P' in codes: print(' P = %s..pcal' % project) if 'p' in codes: print(' p = pcal') if 'C' in codes: print(' C = %s..cablecal' % project) if passName != None and 'D' in codes: print(' D = DiFX extracted (%s_.difx/)' % passName) if passName == None: print('\nWarning: no pass name given. It cannot be determined\nif pulse cal or switched power (for Tsys) was extracted\nby DiFX. It also is not clear which antennas were\ncorrelated; all are assumed.')