#!/usr/bin/env python3 #************************************************************************** # Copyright (C) 2018-2019 by Mark Wainright * # * # 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. * #************************************************************************** # Note: this utility can run under python2.7 or python3 from sys import exit, argv from os.path import isfile, isdir from os import umask, popen, system, getcwd, getenv from shutil import move, copyfile from datetime import * import re program = 'mk62v2d' version = '0.2' verdate = '20190916' author = 'Mark Wainright' MARK6_VSN_IDS = ['%'] MARK5_VSN_IDS = ['+', '-'] def usage(pgm): print('%s ver. %s %s %s\n' % (program, version, author, verdate)) print('Program to update a .v2d file with mark6filelist tags for\n') print('appropriate antennas.\n') print('Program will also create appropriate antenna filelist files.\n') print('Program is called from vex2difx for mark6 related pre-work.\n') print('Usage: %s [options] \n' % pgm) print('options can include\n') print(' --help') print(' -h print this help info and quit\n') print(' --verbose') print(' -v be more verbose in execution (use -v -v for even more!)\n') print(' --quiet') print(' -q be less verbose\n') print(' is a .v2d file that needs mark6filelist tags added\n') exit(0) def getmonthdate(daynumber, yearnumber): md = [0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365] mdl = [0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366] if yearnumber % 4 == 0: dl = mdl else: dl = md for i in range(len(dl)): if daynumber > dl[i] and daynumber <= dl[i+1]: return [i + 1, daynumber - dl[i]] def convertscandata2mjd(scandata): mjd0 = datetime(1858, 11, 17, 0, 0) for scan in scandata: startstr = scan[1] lengthstr = scan[2] if len(startstr) == 18 and startstr[4] == 'y' and startstr[8] == 'd' and startstr[11] == 'h' and startstr[14] == 'm' and startstr[17] == 's': startyear = int(startstr[0:4]) startday = int(startstr[5:8]) mondate = getmonthdate(startday, startyear) startmonth = mondate[0] startdate = mondate[1] starthour = int(startstr[9:11]) startminute = int(startstr[12:14]) startsecond = int(startstr[15:17]) startdt = datetime(startyear, startmonth, startdate, starthour, startminute, startsecond) startmjd = startdt - mjd0 mjdstr = '%.8f' % (startmjd.days + (startmjd.seconds / 86400.0)) scan[1] = mjdstr else: print('invalid start date:', scan[1], 'scan:', scan[0]) continue if lengthstr.split()[0].isdigit() is True: lensec = int(lengthstr.split()[0]) endmjd = startmjd + timedelta(0, lensec) emjdstr = '%.8f' % (endmjd.days + (endmjd.seconds / 86400.0)) scan[2] = emjdstr else: print('could not determine scan length:', scan[2], 'scan:', scan[0]) continue def getvexscandata(station, vexobsfile): vexfile = open(vexobsfile, 'r') schedfound = False firstscanfound = False endscan = True refpoint = False scandata = [] if verbose > 1: print("Parsing vex scan data for station:", station.upper()) for line in vexfile: # find the $SCHED section if schedfound == False: if '$SCHED;' in line: schedfound = True else: # parse scan sections if 'scan ' == line[0:5]: scan = [] if firstscanfound == False: firstscanfound = True labelstart = line.find('scan ') + 5 labelend = line.find(';') label = line[labelstart:labelend] scan.append(label) endscan = False elif 'intent' in line: if 'REFERENCE_POINTING_DETERMINE' in line: refpoint = True else: refpoint = False elif 'start=' in line and '*' not in line: startstart = line.find('start=') + 6 startend = line.find(';') start = line[startstart:startend] scan.append(start) elif 'station=' in line: stationstart = line.find('station=') + 8 stationend = line.find(':') scanstation = line[stationstart:stationend] if station.lower() == scanstation.lower(): stationdata = line.split(':') scanlength = stationdata[2].strip() scan.append(scanlength) elif 'endscan;' == line[0:8] and refpoint == False and len(scan) == 3: scandata.append(scan) endscan = True elif firstscanfound == True and endscan == True: break convertscandata2mjd(scandata) return scandata def getvexantennamodlists(vexobsfile): ''' Returns tuple (experName,antennaModuleList,modList) for Mark6 antennas and VSNs found in the given file with path vexobsfile. On errors this function exits the script. ''' experNameFound = False tapelogObsFound = False experName = '' ant = '' antennaModuleList = [] modList = [] # Regexps to flexibly detect VEX entries and fields; can test with https://regex101.com/ reComment = re.compile("^\s*\*") reSection = re.compile("^\s*\$\s*(.*?)\s*;") reDef = re.compile("^\s*def\s+(.*?)\s*;") reVSN = re.compile("\W*VSN\s*=\s*(.*?)\s*:\s*(.*?)\s*:") reEnddef = re.compile("\W*enddef\s*;") # Look up expt name and module info from VEX vexobs = open(vexobsfile, "r") for line in vexobs: if reComment.match(line): continue # detect EXPER info i = line.find('exper_name') if i != -1: experNameFound = True lineend = line[i+10:len(line)-1] for i in range(len(lineend)): if lineend[i] not in [' ', '=', ';']: experName += lineend[i].upper() continue # detect change of VEX section section = reSection.search(line) if section and tapelogObsFound: # encountered section after TAPELOG_OBS and if expt name also present by now, finished! if experNameFound: break if section and not tapelogObsFound: tapelogObsFound = section.group(1) == 'TAPELOG_OBS' # detect entries in TAPELOG_OBS section if tapelogObsFound: # note the possibility of one-liners e.g. 'def Pv; VSN=0::