Source code for eat.io.ovex

"""
USAGE NOTE:

ovex_reader.Ovex('ovex file name') returns an object that contains
various observational information.

import ovex_reader as ov
fname = "ovex_files/3C279.zmubap"
ovex = ov.Ovex(fname)


Summary of mnemonics:

--- Read in from "$MODE" section in a ovex file
"mode index"=0 if there's only 1 mode
ovex.modes[mode index]['mode'] = name of mode
ovex.modes[mode index]['site_dic'] = dictionary of site name in $FREQ language and site ID in $SITES language

--- Read in from "$FREQ" section in a ovex file
ovex.freqs[site index]['antenna'] = antenna ID
ovex.freqs[site index]['sample_rate'] = sample rate
ovex.freqs[site index]['chans'][channel index]['chan_name'] = name of channel ?
ovex.freqs[site index]['chans'][channel index]['freq'] = frequency in MHz
ovex.freqs[site index]['chans'][channel index]['bw'] = bandwidth in MHz


--- Read in from "$SITES" section in a ovex file
ovex.sites[site index]['site_name']
ovex.sites[site index]['site_ID']
ovex.sites[site index]['mk4_site_ID']
ovex.sites[site index]['site_position']

--- Read in from "$SCHED" section in a ovex file
"scan index"=0 if there's only 1 scan, which is always the case for ovex files ??
ovex.sched[scan index]['scan_numer'] = scan number of "scan ID"-th scan
ovex.sched[scan index]['source'] = source name of "scan ID"-th scan
ovex.sched[scan index]['start'] = start time of the scan
ovex.sched[scan index]['mode'] = scan mode of the scan
ovex.sched[scan index]['scan'][site index]['site'] = site name of "site-ID"-th site of the "scan ID"-th scan
ovex.sched[scan index]['scan'][site index]['scan_sec'] = duration of the scan in second
ovex.sched[scan index]['scan'][site index]['data_size'] = data size (?) of the scan in GB
ovex.sched[scan index]['scan'][site index]['scan_sec_start'] = probably 'start_hr' + 'scan_sec_start'(in sec) is the actual time that the scan starts, but not sure

--- Read in from "$SOURCE" section in a ovex file
"source index"=0 if there's only 1 source
ovex.source[source index]['source'] = source name of "source ID"-th source
ovex.source[source index]['ra'] = RA of the source
ovex.source[source index]['dec'] = DEC of the source
ovex.source[source index]['ref_coord_frame'] = something about the source

--- Others
ovex.sites_dic = sites' names in various languages (site_name, site_ID, mk4_site_ID, $FREQ's ref)
ovex.lvex_rev
ovex.evex_rev
ovex.ivex_rev
"""
from __future__ import print_function


# from builtins import range
# from builtins import object
import numpy as np
import re
#import jdcal


[docs]class Ovex(object): def __init__(self, filename): f = open(filename) raw = f.readlines() f.close() self.filename = filename # Divide 'raw' data into sectors of '$' marks # ASSUMING '$' is the very first character in a line (no space in front) metalist = [] # meaning list of metadata for i in range(len(raw)): if raw[i][0]=='$': temp = [raw[i]] break for j in range(i+1,len(raw)): if raw[j][0]!='$': temp.append(raw[j]) elif raw[j][0]=='$': metalist.append(temp) temp = [raw[j]] else: print('Something is wrong.') metalist.append(temp) # don't forget to add the final one self.metalist = metalist # MODE ========================================================== MODE = self.get_sector('MODE') modes = [] indef = False for i in range(len(MODE)): line = MODE[i] if indef==False: idx = self.find_variable('def',line) if idx>=0: temp = {} temp['mode'] = self.get_def_name(line) temp['site_dic'] = {} cnt = 0 indef=True if indef==True: idx = self.find_variable('ref',line) var = self.get_ref_special('$FREQ',line) if var!=False: temp['site_dic'][cnt] = var cnt += 1 if indef==True: idx = self.find_variable('enddef',line) if idx>=0: modes.append(temp) indef=False self.modes = modes # Extract desired information # SOURCE ======================================================== SOURCE = self.get_sector('SOURCE') source = [] indef = False for i in range(len(SOURCE)): line = SOURCE[i] if line[0:3]=="def": indef=True if indef: ret = self.get_variable("source_name",line) if len(ret)>0: source_name = ret ret = self.get_variable("ra",line) if len(ret)>0: ra = ret ret = self.get_variable("dec",line) if len(ret)>0: dec = ret ret = self.get_variable("ref_coord_frame",line) if len(ret)>0: ref_coord_frame = ret if line[0:6]=="enddef": source.append({'source':source_name,'ra':ra,'dec':dec,'ref_coord_frame':ref_coord_frame}) indef=False self.source = source # FREQ ========================================================== FREQ = self.get_sector('FREQ') freq = [] indef = False for i in range(len(FREQ)): line = FREQ[i] if indef==False: idx = self.find_variable('def',line) if idx>=0: temp = {} temp['chans'] = {} cnt = 0 temp['antenna'] = self.get_def_name(line) indef=True if indef: idx = line.find('chan_def') if idx>=0: chan_name = self.get_variable("chan_def",line) chan_def = re.findall("[-+]?\d+[\.]?\d*",line) temp['chans'][cnt] = {'chan_name':chan_name,'freq':float(chan_def[1]),'bw':float(chan_def[2])} #MHz cnt+=1 ret = self.get_variable("sample_rate",line) if len(ret)>0: temp['sample_rate'] = ret if indef==True: idx = self.find_variable('enddef',line) if idx>=0: freq.append(temp) indef=False self.freqs = freq # SITE ========================================================== SITE = self.get_sector('SITE') sites = [] site_ID_dict = {} indef = False for i in range(len(SITE)): line = SITE[i] if line[0:3]=="def": indef=True if indef: # get site_name ret = self.get_variable("site_name",line) if len(ret)>0: site_name = ret # get site_ID and make dictionrary for site_ID <-> site_name ret = self.get_variable("site_ID",line) if len(ret)>0: site_ID = ret site_ID_dict[ret] = site_name # get site_position ret = self.get_variable("site_position",line) if len(ret)>0: site_position = re.findall("[-+]?\d+[\.]?\d*",line) # get mk4_site_ID ret = self.get_variable("mk4_site_ID",line) if len(ret)>0: mk4_site_ID = ret # append to "sites" if line[0:6]=="enddef": #sites.append([site_name,site_ID,mk4_site_ID,site_position[0],site_position[1],site_position[2]]) sites.append({'site_name':site_name,'site_ID':site_ID,'mk4_site_ID':mk4_site_ID,'site_position':site_position}) indef=False self.sites = sites # SCHED ========================================================= SCHED = self.get_sector('SCHED') sched = [] inscan = False for i in range(len(SCHED)): line = SCHED[i] if line[0:4]=="scan": inscan=True temp={} temp['scan_number'] = re.findall("[-+]?\d+[\.]?\d*",line) temp['scan']={} cnt = 0 if inscan: ret = self.get_variable("start",line) if len(ret)>0: #mjd,hr = self.vexdate_to_MJD_hr(ret) # convert vex time format to mjd and hour #temp['mjd_floor'] = mjd #temp['start_hr'] = hr temp['start'] = ret ret = self.get_variable("mode",line) if len(ret)>0: temp['mode'] = ret ret = self.get_variable("source",line) if len(ret)>0: temp['source'] = ret ret = self.get_variable("station",line) if len(ret)>0: site_ID = ret site_name = site_ID_dict[site_ID] # convert to more familier site name sdur = re.findall("[-+]?\d+[\.]?\d*",line) s_st = float(sdur[0]) # start time in sec s_en = float(sdur[1]) # end time in sec d_size = float(sdur[2]) # data size(?) in GB temp['scan'][cnt] = {'site':site_name,'scan_sec_start':s_st,'scan_sec':s_en,'data_size':d_size} cnt +=1 if line[0:7]=="endscan": sched.append(temp) inscan=False self.sched = sched # LVEX_REV ===================================================== LVEX_REV = self.get_sector('LVEX_REV') for i in range(len(LVEX_REV)): line = LVEX_REV[i] ret = self.get_variable("rev",line) if len(ret)>0: self.lvex_rev = float(ret) # EVEX_REV ===================================================== EVEX_REV = self.get_sector('EVEX_REV') for i in range(len(EVEX_REV)): line = EVEX_REV[i] ret = self.get_variable("rev",line) if len(ret)>0: self.evex_rev = float(ret) # IVEX_REV ===================================================== IVEX_REV = self.get_sector('IVEX_REV') for i in range(len(IVEX_REV)): line = IVEX_REV[i] ret = self.get_variable("rev",line) if len(ret)>0: self.ivex_rev = float(ret) # list of various ways of calling the same site ================ sites_dic = [] for i in range(len(self.modes[0]['site_dic'])): id0 = site_ID_dict[self.modes[0]['site_dic'][i][1]] id1 = self.modes[0]['site_dic'][i][1] for j in range(len(self.sites)): if self.sites[j]['site_ID'] == id1: id2 = self.sites[j]['mk4_site_ID'] id3 = self.modes[0]['site_dic'][i][0] sites_dic.append([id0,id1,id2,id3]) self.sites_dic = sites_dic # ==================================================================== # ==================================================================== # Function to obtain a desired sector from 'metalist'
[docs] def get_sector(self, sname): for i in range(len(self.metalist)): if sname in self.metalist[i][0]: return self.metalist[i] print('No sector named %s'%sname) return False
# Function to get a value of 'vname' in a line which has format of # 'vname' = value ;(or :)
[docs] def get_variable(self, vname, line): idx = self.find_variable(vname,line) name = '' if idx>=0: start = False for i in range(idx+len(vname),len(line)): if start==True: if line[i]==';' or line[i]==':': break elif line[i]!=' ': name += line[i] if start==False and line[i]!=' ' and line[i]!='=': break if line[i]=='=': start = True return name
# Function to find MJD (int!) and hour in UT from vex format, # e.g, 2016y099d05h00m00s """ def vexdate_to_MJD_hr(self, vexdate): time = re.findall("[-+]?\d+[\.]?\d*",vexdate) year = int(time[0]) date = int(time[1]) mjd = jdcal.gcal2jd(year,1,1)[1]+date-1 hour = int(time[2]) + float(time[3])/60. + float(time[4])/60./60. return mjd,hour """ # check if a variable 'vname' exists by itself in a line. # returns index of vname[0] in a line, or -1
[docs] def find_variable(self, vname, line): idx = line.find(vname) if ((idx>0 and line[idx-1]==' ') or idx==0) and line[0]!='*': if idx+len(vname)==len(line): return idx if line[idx+len(vname)]=='=' or line[idx+len(vname)]==' ' or line[idx+len(vname)]==':' or line[idx+len(vname)]==';': return idx return -1
# extract def 'def_name'; (or :)
[docs] def get_def_name(self, line): idx = self.find_variable('def', line) if idx<0: return False var = '' invar = False for i in range(idx+3,len(line)): if invar == True and (line[i]==' ' or line[i]==';' or line[i]==':'): return var if line[i]!=' ': invar = True if invar==True: var += line[i] return False
# extract 'ref $FREQ = ant00:Aa;' kind of format
[docs] def get_ref_special(self, vname, line): idx = self.find_variable('ref', line) if idx<0: return False line = line[idx+3:] idx = self.find_variable(vname, line) if idx<0: return False var1 = self.get_variable(vname,line) idx = line.find(var1) for i in range(idx+len(var1),len(line)): if line[i]==';' or line[i]==':': break idx = i+1 var2 = '' invar = False for i in range(idx,len(line)): if invar == True and (line[i]==' ' or line[i]==';' or line[i]==':'): break if invar == False and line[i]!=' ': invar = True if invar==True: var2 += line[i] return var1,var2