|
|
#!PYTHONEXE
|
|
|
|
|
|
"""createRecordPlots.py is a script to create all the individual record plots
|
|
|
for an ISR Madrigal file. Plots Ti, Te, Vi, and Nel (or Popl) vs altitude,
|
|
|
and puts plots in proper place in Madrigal experiment.
|
|
|
|
|
|
usage: createRecordPlots.py <full path to madrigal file>
|
|
|
|
|
|
"""
|
|
|
|
|
|
#$Id: createRecordPlots.py 7284 2020-11-24 14:55:43Z brideout $
|
|
|
|
|
|
usage = 'createRecordPlots.py <full path to madrigal file>'
|
|
|
|
|
|
# standard python imports
|
|
|
import sys
|
|
|
import os, os.path
|
|
|
import datetime
|
|
|
import traceback
|
|
|
import math
|
|
|
import argparse
|
|
|
|
|
|
# third party imports
|
|
|
import numpy
|
|
|
|
|
|
# Madrigal imports
|
|
|
import madrigal.metadata
|
|
|
import madrigalWeb.madrigalWeb
|
|
|
import madrigal.ui.madrigalPlot
|
|
|
|
|
|
def getSummaryStr(values, madFile, madInstObj, madKindatObj, rangeResl):
|
|
|
"""getSummaryStr builds the summary string from the isprint values
|
|
|
|
|
|
Inputs:
|
|
|
|
|
|
values - a list of strings from a single isprint line
|
|
|
|
|
|
madFile - madrigal file name being plotted
|
|
|
|
|
|
madInstObj - a madrigal.metadata.MadrigalInstrument object
|
|
|
|
|
|
madKindatObj - a madrigal.metadata.MadrigalKindat object
|
|
|
|
|
|
rangeResl - range resolution. If None, unknown or varying; do not print
|
|
|
|
|
|
"""
|
|
|
retStr = ''
|
|
|
kinst = int(values[12])
|
|
|
retStr += 'Instrument: %s\n' % (madInstObj.getInstrumentName(kinst))
|
|
|
year = int(values[14])
|
|
|
month = int(values[15])
|
|
|
day = int(values[16])
|
|
|
retStr += '%04i-%02i-%02i\n' % (year, month,day)
|
|
|
bhhmmss = int(values[17])
|
|
|
ehhmmss = int(values[18])
|
|
|
bh = bhhmmss // 10000
|
|
|
bm = (bhhmmss - (bh*10000)) // 100
|
|
|
bs = bhhmmss % 100
|
|
|
eh = ehhmmss // 10000
|
|
|
em = (ehhmmss - (eh*10000)) // 100
|
|
|
es = ehhmmss % 100
|
|
|
retStr += '%02i:%02i:%02i - %02i:%02i:%02i\n' % (bh,bm,bs,eh,em,es)
|
|
|
retStr += 'Record #%i\n' % (int(values[0]))
|
|
|
kindatStr = madKindatObj.getKindatDescription(int(values[13]), kinst)
|
|
|
if kindatStr != None:
|
|
|
retStr += 'Kindat: %s\n' % (kindatStr)
|
|
|
try:
|
|
|
azm = float(values[19])
|
|
|
retStr += 'Az = %5.2f\n' % (azm)
|
|
|
except:
|
|
|
pass
|
|
|
try:
|
|
|
elm = float(values[20])
|
|
|
retStr += 'El = %5.2f\n' % (elm)
|
|
|
except:
|
|
|
pass
|
|
|
try:
|
|
|
systmp = float(values[21])
|
|
|
retStr += 'System temperature = %i K\n' % (int(systmp))
|
|
|
except:
|
|
|
pass
|
|
|
try:
|
|
|
pl = float(values[22])
|
|
|
retStr += 'Pulse length = %i microsec\n' % (int(pl*1e6))
|
|
|
except:
|
|
|
pass
|
|
|
|
|
|
try:
|
|
|
ipp = float(values[23])
|
|
|
retStr += 'IPP = %i microsec\n' % (int(ipp*1e6))
|
|
|
except:
|
|
|
pass
|
|
|
|
|
|
if rangeResl != None:
|
|
|
retStr += 'Range resolution = %i km\n' % (int(rangeResl))
|
|
|
|
|
|
retStr += '\n%s\n' % (os.path.basename(madFile))
|
|
|
retStr += 'Plotted - %s' % (datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S'))
|
|
|
|
|
|
# check whether any wrapping required
|
|
|
replacePointList = []
|
|
|
totalLen = 0
|
|
|
lineList = retStr.split('\n')
|
|
|
for line in lineList:
|
|
|
if len(line) > 50:
|
|
|
replacePointList.append(totalLen + line[:50].rfind(' '))
|
|
|
totalLen += (len(line) + 1)
|
|
|
|
|
|
for point in replacePointList:
|
|
|
retStr = retStr[:point] + '\n' + retStr[point+1:]
|
|
|
|
|
|
|
|
|
return retStr
|
|
|
|
|
|
def getNelError(logNe, logDNe):
|
|
|
"""getNelError is used to convert the Cedar standard logarithm
|
|
|
of the uncertainty (logDNe), into uncertainty of the logarithm.
|
|
|
Returns (lower value, upper value)
|
|
|
"""
|
|
|
Ne = math.pow(10.0, logNe)
|
|
|
dNe = math.pow(10.0, logDNe)
|
|
|
lowerNe = Ne-dNe
|
|
|
if lowerNe < 1.0:
|
|
|
lowerNe = 1.0
|
|
|
upperNe = Ne+dNe
|
|
|
lowerDNe = logNe - math.log10(lowerNe)
|
|
|
upperDNe = math.log10(upperNe) - logNe
|
|
|
|
|
|
return ((lowerDNe, upperDNe))
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
############## main script begins here ##############
|
|
|
|
|
|
# script begins here
|
|
|
if __name__ == '__main__':
|
|
|
|
|
|
parser = argparse.ArgumentParser(description='createRecordPlots.py is a script to create all the individual record plots for an ISR Madrigal file')
|
|
|
parser.add_argument('--skipExisting', action='store_true', help='skip existing plots')
|
|
|
parser.add_argument('madFile', help='Full path to Madrigal ISR file to plot')
|
|
|
|
|
|
args = parser.parse_args()
|
|
|
|
|
|
madFile = args.madFile
|
|
|
|
|
|
if madFile[0] != '/':
|
|
|
raise ValueError('Full path to madrigal file must be used, not %s' % (str(madFile)))
|
|
|
|
|
|
madDir = os.path.dirname(madFile)
|
|
|
madBasename = os.path.basename(madFile)
|
|
|
|
|
|
# create plotDir if needed
|
|
|
plotDir = os.path.join(madDir, 'plots', madBasename, 'records')
|
|
|
|
|
|
try:
|
|
|
os.makedirs(plotDir)
|
|
|
except:
|
|
|
pass
|
|
|
|
|
|
madDBObj = madrigal.metadata.MadrigalDB()
|
|
|
madInstObj = madrigal.metadata.MadrigalInstrument(madDBObj)
|
|
|
madKindatObj = madrigal.metadata.MadrigalKindat(madDBObj)
|
|
|
|
|
|
url = madDBObj.getTopLevelUrl()
|
|
|
|
|
|
# create madrigalWeb Object
|
|
|
madWebObj = madrigalWeb.madrigalWeb.MadrigalData(url)
|
|
|
|
|
|
parameters = 'recno,gdalt,ti,dti,te,dte,vo,dvo,popl,dpopl,nel,dnel,kinst,kindat,' + \
|
|
|
'year,month,day,bhhmmss,ehhmmss,azm,elm,systmp,pl,ipp,resl'
|
|
|
user_fullname = 'administrator'
|
|
|
user_email = 'admin'
|
|
|
user_affiliation = 'local'
|
|
|
filters = 'z=0,600'
|
|
|
|
|
|
# get data
|
|
|
data = madWebObj.isprint(madFile,
|
|
|
parameters,
|
|
|
filters,
|
|
|
user_fullname,
|
|
|
user_email,
|
|
|
user_affiliation)
|
|
|
|
|
|
data = data.strip()
|
|
|
|
|
|
# parse data into numeric arrays
|
|
|
tiList = []
|
|
|
tiErrList = []
|
|
|
teList = []
|
|
|
teErrList = []
|
|
|
voList = []
|
|
|
voErrList = []
|
|
|
poplList = []
|
|
|
poplErrList = []
|
|
|
nelList = []
|
|
|
nelErrList = []
|
|
|
lines = data.split('\n')
|
|
|
recno = None
|
|
|
values = None
|
|
|
prevRangeResl = None # check if range resolutions vary
|
|
|
rangeReslOkay = True
|
|
|
thisEl = None
|
|
|
count = 0 # print records processed
|
|
|
for i in range(len(lines)):
|
|
|
line = lines[i]
|
|
|
lastValues = values
|
|
|
values = line.split()
|
|
|
if len(values) < 3:
|
|
|
continue
|
|
|
nextRecno = int(values[0])
|
|
|
|
|
|
try:
|
|
|
nextRangeResl = int(round(float(values[24])))
|
|
|
if prevRangeResl == None:
|
|
|
rangeReslOkay = True
|
|
|
prevRangeResl = nextRangeResl
|
|
|
except:
|
|
|
nextRangeResl = None
|
|
|
rangeReslOkay = False
|
|
|
try:
|
|
|
thisEl = float(values[20])
|
|
|
thisAltResl = round(prevRangeResl*math.sin(math.radians(thisEl)))
|
|
|
except:
|
|
|
thisAltResl = None
|
|
|
if not rangeReslOkay:
|
|
|
thisAltResl = None
|
|
|
if recno == None:
|
|
|
recno = nextRecno
|
|
|
if prevRangeResl != nextRangeResl and recno == nextRecno:
|
|
|
# range resolutions are changing
|
|
|
rangeReslOkay = False
|
|
|
if nextRecno != recno or i == len(lines)-1:
|
|
|
# plot existing record
|
|
|
summaryStr = getSummaryStr(lastValues, madFile, madInstObj, madKindatObj, prevRangeResl)
|
|
|
tiArray = numpy.array(tiList)
|
|
|
tiErrArray = numpy.array(tiErrList)
|
|
|
teArray = numpy.array(teList)
|
|
|
teErrArray = numpy.array(teErrList)
|
|
|
voArray = numpy.array(voList)
|
|
|
voErrArray = numpy.array(voErrList)
|
|
|
if len(poplList) > 0:
|
|
|
poplArray = numpy.array(poplList)
|
|
|
if numpy.all(numpy.isnan(poplArray[:,0])):
|
|
|
isPopl = False
|
|
|
else:
|
|
|
poplErrArray = numpy.array(poplErrList)
|
|
|
isPopl = True
|
|
|
else:
|
|
|
isPopl = False
|
|
|
if not isPopl:
|
|
|
poplArray = numpy.array(nelList)
|
|
|
poplErrArray = numpy.array(nelErrList)
|
|
|
isPopl = False
|
|
|
|
|
|
plotExists = os.path.exists(os.path.join(plotDir, 'plot%05i.png' % (recno)))
|
|
|
if plotExists and args.skipExisting:
|
|
|
pass
|
|
|
else:
|
|
|
|
|
|
try:
|
|
|
obj = madrigal.ui.madrigalPlot.madIsrRecordSummary(tiArray,
|
|
|
tiErrArray,
|
|
|
teArray,
|
|
|
teErrArray,
|
|
|
voArray,
|
|
|
voErrArray,
|
|
|
poplArray,
|
|
|
numpy.transpose(poplErrArray),
|
|
|
isPopl,
|
|
|
summaryStr,
|
|
|
os.path.join(plotDir, 'plot%05i.png' % (recno)),
|
|
|
altResl=thisAltResl)
|
|
|
except:
|
|
|
traceback.print_exc()
|
|
|
print('plot %i raised error' % (count))
|
|
|
print(count)
|
|
|
|
|
|
obj = None
|
|
|
prevRangeResl = None
|
|
|
count += 1
|
|
|
|
|
|
tiList = []
|
|
|
tiErrList = []
|
|
|
teList = []
|
|
|
teErrList = []
|
|
|
voList = []
|
|
|
voErrList = []
|
|
|
poplList = []
|
|
|
poplErrList = []
|
|
|
nelList = []
|
|
|
nelErrList = []
|
|
|
|
|
|
recno = nextRecno
|
|
|
try:
|
|
|
gdalt = float(values[1])
|
|
|
except:
|
|
|
continue
|
|
|
try:
|
|
|
ti = float(values[2])
|
|
|
tiErr = float(values[3])
|
|
|
tiList.append((ti, gdalt))
|
|
|
tiErrList.append(tiErr)
|
|
|
except:
|
|
|
pass
|
|
|
try:
|
|
|
te = float(values[4])
|
|
|
teErr = float(values[5])
|
|
|
teList.append((te, gdalt))
|
|
|
teErrList.append(teErr)
|
|
|
except:
|
|
|
pass
|
|
|
try:
|
|
|
vo = float(values[6])
|
|
|
voErr = float(values[7])
|
|
|
voList.append((vo, gdalt))
|
|
|
voErrList.append(voErr)
|
|
|
except:
|
|
|
pass
|
|
|
try:
|
|
|
popl = float(values[8])
|
|
|
try:
|
|
|
poplErr = float(values[9])
|
|
|
except:
|
|
|
poplErr = 0.0 # no error data
|
|
|
poplList.append((popl, gdalt))
|
|
|
poplErrList.append(getNelError(popl, poplErr))
|
|
|
except:
|
|
|
pass
|
|
|
try:
|
|
|
nel = float(values[10])
|
|
|
try:
|
|
|
nelErr = float(values[11])
|
|
|
except:
|
|
|
nelErr = 0.0 # no error data
|
|
|
nelList.append((nel, gdalt))
|
|
|
nelErrList.append(getNelError(nel, nelErr))
|
|
|
except:
|
|
|
pass
|
|
|
|
|
|
|
|
|
|
|
|
|