BLTRheaderIO.py
403 lines
| 16.3 KiB
| text/x-python
|
PythonLexer
|
r965 | ''' | |
$Author: murco $ | |||
$Id: JROHeaderIO.py 151 2012-10-31 19:00:51Z murco $ | |||
''' | |||
import sys | |||
import numpy | |||
import copy | |||
import datetime | |||
|
r1167 | ||
|
r965 | ||
SPEED_OF_LIGHT = 299792458 | |||
SPEED_OF_LIGHT = 3e8 | |||
FILE_STRUCTURE = numpy.dtype([ #HEADER 48bytes | |||
('FileMgcNumber','<u4'), #0x23020100 | |||
('nFDTdataRecors','<u4'), #No Of FDT data records in this file (0 or more) | |||
('RadarUnitId','<u4'), | |||
('SiteName','<s32'), #Null terminated | |||
]) | |||
RECORD_STRUCTURE = numpy.dtype([ #RECORD HEADER 180+20N bytes | |||
('RecMgcNumber','<u4'), #0x23030001 | |||
('RecCounter','<u4'), #Record counter(0,1, ...) | |||
('Off2StartNxtRec','<u4'), #Offset to start of next record form start of this record | |||
('Off2StartData','<u4'), #Offset to start of data from start of this record | |||
('EpTimeStamp','<i4'), #Epoch time stamp of start of acquisition (seconds) | |||
('msCompTimeStamp','<u4'), #Millisecond component of time stamp (0,...,999) | |||
('ExpTagName','<s32'), #Experiment tag name (null terminated) | |||
('ExpComment','<s32'), #Experiment comment (null terminated) | |||
('SiteLatDegrees','<f4'), #Site latitude (from GPS) in degrees (positive implies North) | |||
('SiteLongDegrees','<f4'), #Site longitude (from GPS) in degrees (positive implies East) | |||
('RTCgpsStatus','<u4'), #RTC GPS engine status (0=SEEK, 1=LOCK, 2=NOT FITTED, 3=UNAVAILABLE) | |||
('TransmitFrec','<u4'), #Transmit frequency (Hz) | |||
('ReceiveFrec','<u4'), #Receive frequency | |||
('FirstOsciFrec','<u4'), #First local oscillator frequency (Hz) | |||
('Polarisation','<u4'), #(0="O", 1="E", 2="linear 1", 3="linear2") | |||
('ReceiverFiltSett','<u4'), #Receiver filter settings (0,1,2,3) | |||
('nModesInUse','<u4'), #Number of modes in use (1 or 2) | |||
('DualModeIndex','<u4'), #Dual Mode index number for these data (0 or 1) | |||
('DualModeRange','<u4'), #Dual Mode range correction for these data (m) | |||
('nDigChannels','<u4'), #Number of digital channels acquired (2*N) | |||
('SampResolution','<u4'), #Sampling resolution (meters) | |||
('nRangeGatesSamp','<u4'), #Number of range gates sampled | |||
('StartRangeSamp','<u4'), #Start range of sampling (meters) | |||
('PRFhz','<u4'), #PRF (Hz) | |||
('Integrations','<u4'), #Integrations | |||
('nDataPointsTrsf','<u4'), #Number of data points transformed | |||
('nReceiveBeams','<u4'), #Number of receive beams stored in file (1 or N) | |||
('nSpectAverages','<u4'), #Number of spectral averages | |||
('FFTwindowingInd','<u4'), #FFT windowing index (0 = no window) | |||
('BeamAngleAzim','<f4'), #Beam steer angle (azimuth) in degrees (clockwise from true North) | |||
('BeamAngleZen','<f4'), #Beam steer angle (zenith) in degrees (0=> vertical) | |||
('AntennaCoord','<f24'), #Antenna coordinates (Range(meters), Bearing(degrees)) - N pairs | |||
('RecPhaseCalibr','<f12'), #Receiver phase calibration (degrees) - N values | |||
('RecAmpCalibr','<f12'), #Receiver amplitude calibration (ratio relative to receiver one) - N values | |||
('ReceiverGaindB','<u12'), #Receiver gains in dB - N values | |||
]) | |||
class Header(object): | |||
def __init__(self): | |||
raise NotImplementedError | |||
def read(self): | |||
raise NotImplementedError | |||
def write(self): | |||
raise NotImplementedError | |||
def printInfo(self): | |||
message = "#"*50 + "\n" | |||
message += self.__class__.__name__.upper() + "\n" | |||
message += "#"*50 + "\n" | |||
|
r1167 | keyList = list(self.__dict__.keys()) | |
|
r965 | keyList.sort() | |
for key in keyList: | |||
message += "%s = %s" %(key, self.__dict__[key]) + "\n" | |||
if "size" not in keyList: | |||
attr = getattr(self, "size") | |||
if attr: | |||
message += "%s = %s" %("size", attr) + "\n" | |||
|
r1167 | print(message) | |
|
r965 | ||
class FileHeader(Header): | |||
FileMgcNumber= None | |||
nFDTdataRecors=None #No Of FDT data records in this file (0 or more) | |||
RadarUnitId= None | |||
SiteName= None | |||
#__LOCALTIME = None | |||
def __init__(self, useLocalTime=True): | |||
self.FileMgcNumber= 0 #0x23020100 | |||
self.nFDTdataRecors=0 #No Of FDT data records in this file (0 or more) | |||
self.RadarUnitId= 0 | |||
self.SiteName= "" | |||
self.size = 48 | |||
#self.useLocalTime = useLocalTime | |||
def read(self, fp): | |||
try: | |||
header = numpy.fromfile(fp, FILE_STRUCTURE,1) | |||
''' numpy.fromfile(file, dtype, count, sep='') | |||
file : file or str | |||
Open file object or filename. | |||
dtype : data-type | |||
Data type of the returned array. For binary files, it is used to determine | |||
the size and byte-order of the items in the file. | |||
count : int | |||
Number of items to read. -1 means all items (i.e., the complete file). | |||
sep : str | |||
Separator between items if file is a text file. Empty (“”) separator means | |||
the file should be treated as binary. Spaces (” ”) in the separator match zero | |||
or more whitespace characters. A separator consisting only of spaces must match | |||
at least one whitespace. | |||
''' | |||
|
r1167 | except Exception as e: | |
print("FileHeader: ") | |||
print(eBasicHeader) | |||
|
r965 | return 0 | |
self.FileMgcNumber= byte(header['FileMgcNumber'][0]) | |||
self.nFDTdataRecors=int(header['nFDTdataRecors'][0]) #No Of FDT data records in this file (0 or more) | |||
self.RadarUnitId= int(header['RadarUnitId'][0]) | |||
self.SiteName= char(header['SiteName'][0]) | |||
if self.size <48: | |||
return 0 | |||
return 1 | |||
def write(self, fp): | |||
headerTuple = (self.FileMgcNumber, | |||
self.nFDTdataRecors, | |||
self.RadarUnitId, | |||
self.SiteName, | |||
self.size) | |||
header = numpy.array(headerTuple, FILE_STRUCTURE) | |||
# numpy.array(object, dtype=None, copy=True, order=None, subok=False, ndmin=0) | |||
header.tofile(fp) | |||
''' ndarray.tofile(fid, sep, format) Write array to a file as text or binary (default). | |||
fid : file or str | |||
An open file object, or a string containing a filename. | |||
sep : str | |||
Separator between array items for text output. If “” (empty), a binary file is written, | |||
equivalent to file.write(a.tobytes()). | |||
format : str | |||
Format string for text file output. Each entry in the array is formatted to text by | |||
first converting it to the closest Python type, and then using “format” % item. | |||
''' | |||
return 1 | |||
class RecordHeader(Header): | |||
RecMgcNumber=None #0x23030001 | |||
RecCounter= None | |||
Off2StartNxtRec= None | |||
EpTimeStamp= None | |||
msCompTimeStamp= None | |||
ExpTagName= None | |||
ExpComment=None | |||
SiteLatDegrees=None | |||
SiteLongDegrees= None | |||
RTCgpsStatus= None | |||
TransmitFrec= None | |||
ReceiveFrec= None | |||
FirstOsciFrec= None | |||
Polarisation= None | |||
ReceiverFiltSett= None | |||
nModesInUse= None | |||
DualModeIndex= None | |||
DualModeRange= None | |||
nDigChannels= None | |||
SampResolution= None | |||
nRangeGatesSamp= None | |||
StartRangeSamp= None | |||
PRFhz= None | |||
Integrations= None | |||
nDataPointsTrsf= None | |||
nReceiveBeams= None | |||
nSpectAverages= None | |||
FFTwindowingInd= None | |||
BeamAngleAzim= None | |||
BeamAngleZen= None | |||
AntennaCoord= None | |||
RecPhaseCalibr= None | |||
RecAmpCalibr= None | |||
ReceiverGaindB= None | |||
'''size = None | |||
nSamples = None | |||
nProfiles = None | |||
nChannels = None | |||
adcResolution = None | |||
pciDioBusWidth = None''' | |||
def __init__(self, RecMgcNumber=None, RecCounter= 0, Off2StartNxtRec= 0, | |||
EpTimeStamp= 0, msCompTimeStamp= 0, ExpTagName= None, | |||
ExpComment=None, SiteLatDegrees=0, SiteLongDegrees= 0, | |||
RTCgpsStatus= 0, TransmitFrec= 0, ReceiveFrec= 0, | |||
FirstOsciFrec= 0, Polarisation= 0, ReceiverFiltSett= 0, | |||
nModesInUse= 0, DualModeIndex= 0, DualModeRange= 0, | |||
nDigChannels= 0, SampResolution= 0, nRangeGatesSamp= 0, | |||
StartRangeSamp= 0, PRFhz= 0, Integrations= 0, | |||
nDataPointsTrsf= 0, nReceiveBeams= 0, nSpectAverages= 0, | |||
FFTwindowingInd= 0, BeamAngleAzim= 0, BeamAngleZen= 0, | |||
AntennaCoord= 0, RecPhaseCalibr= 0, RecAmpCalibr= 0, | |||
ReceiverGaindB= 0): | |||
self.RecMgcNumber = RecMgcNumber #0x23030001 | |||
self.RecCounter = RecCounter | |||
self.Off2StartNxtRec = Off2StartNxtRec | |||
self.EpTimeStamp = EpTimeStamp | |||
self.msCompTimeStamp = msCompTimeStamp | |||
self.ExpTagName = ExpTagName | |||
self.ExpComment = ExpComment | |||
self.SiteLatDegrees = SiteLatDegrees | |||
self.SiteLongDegrees = SiteLongDegrees | |||
self.RTCgpsStatus = RTCgpsStatus | |||
self.TransmitFrec = TransmitFrec | |||
self.ReceiveFrec = ReceiveFrec | |||
self.FirstOsciFrec = FirstOsciFrec | |||
self.Polarisation = Polarisation | |||
self.ReceiverFiltSett = ReceiverFiltSett | |||
self.nModesInUse = nModesInUse | |||
self.DualModeIndex = DualModeIndex | |||
self.DualModeRange = DualModeRange | |||
self.nDigChannels = nDigChannels | |||
self.SampResolution = SampResolution | |||
self.nRangeGatesSamp = nRangeGatesSamp | |||
self.StartRangeSamp = StartRangeSamp | |||
self.PRFhz = PRFhz | |||
self.Integrations = Integrations | |||
self.nDataPointsTrsf = nDataPointsTrsf | |||
self.nReceiveBeams = nReceiveBeams | |||
self.nSpectAverages = nSpectAverages | |||
self.FFTwindowingInd = FFTwindowingInd | |||
self.BeamAngleAzim = BeamAngleAzim | |||
self.BeamAngleZen = BeamAngleZen | |||
self.AntennaCoord = AntennaCoord | |||
self.RecPhaseCalibr = RecPhaseCalibr | |||
self.RecAmpCalibr = RecAmpCalibr | |||
self.ReceiverGaindB = ReceiverGaindB | |||
def read(self, fp): | |||
startFp = fp.tell() #The method tell() returns the current position of the file read/write pointer within the file. | |||
try: | |||
header = numpy.fromfile(fp,RECORD_STRUCTURE,1) | |||
|
r1167 | except Exception as e: | |
print("System Header: " + e) | |||
|
r965 | return 0 | |
self.RecMgcNumber = header['RecMgcNumber'][0] #0x23030001 | |||
self.RecCounter = header['RecCounter'][0] | |||
self.Off2StartNxtRec = header['Off2StartNxtRec'][0] | |||
self.EpTimeStamp = header['EpTimeStamp'][0] | |||
self.msCompTimeStamp = header['msCompTimeStamp'][0] | |||
self.ExpTagName = header['ExpTagName'][0] | |||
self.ExpComment = header['ExpComment'][0] | |||
self.SiteLatDegrees = header['SiteLatDegrees'][0] | |||
self.SiteLongDegrees = header['SiteLongDegrees'][0] | |||
self.RTCgpsStatus = header['RTCgpsStatus'][0] | |||
self.TransmitFrec = header['TransmitFrec'][0] | |||
self.ReceiveFrec = header['ReceiveFrec'][0] | |||
self.FirstOsciFrec = header['FirstOsciFrec'][0] | |||
self.Polarisation = header['Polarisation'][0] | |||
self.ReceiverFiltSett = header['ReceiverFiltSett'][0] | |||
self.nModesInUse = header['nModesInUse'][0] | |||
self.DualModeIndex = header['DualModeIndex'][0] | |||
self.DualModeRange = header['DualModeRange'][0] | |||
self.nDigChannels = header['nDigChannels'][0] | |||
self.SampResolution = header['SampResolution'][0] | |||
self.nRangeGatesSamp = header['nRangeGatesSamp'][0] | |||
self.StartRangeSamp = header['StartRangeSamp'][0] | |||
self.PRFhz = header['PRFhz'][0] | |||
self.Integrations = header['Integrations'][0] | |||
self.nDataPointsTrsf = header['nDataPointsTrsf'][0] | |||
self.nReceiveBeams = header['nReceiveBeams'][0] | |||
self.nSpectAverages = header['nSpectAverages'][0] | |||
self.FFTwindowingInd = header['FFTwindowingInd'][0] | |||
self.BeamAngleAzim = header['BeamAngleAzim'][0] | |||
self.BeamAngleZen = header['BeamAngleZen'][0] | |||
self.AntennaCoord = header['AntennaCoord'][0] | |||
self.RecPhaseCalibr = header['RecPhaseCalibr'][0] | |||
self.RecAmpCalibr = header['RecAmpCalibr'][0] | |||
self.ReceiverGaindB = header['ReceiverGaindB'][0] | |||
Self.size = 180+20*3 | |||
endFp = self.size + startFp | |||
if fp.tell() > endFp: | |||
sys.stderr.write("Warning %s: Size value read from System Header is lower than it has to be\n" %fp.name) | |||
return 0 | |||
if fp.tell() < endFp: | |||
sys.stderr.write("Warning %s: Size value read from System Header size is greater than it has to be\n" %fp.name) | |||
return 0 | |||
return 1 | |||
def write(self, fp): | |||
headerTuple = (self.RecMgcNumber, | |||
self.RecCounter, | |||
self.Off2StartNxtRec, | |||
self.EpTimeStamp, | |||
self.msCompTimeStamp, | |||
self.ExpTagName, | |||
self.ExpComment, | |||
self.SiteLatDegrees, | |||
self.SiteLongDegrees, | |||
self.RTCgpsStatus, | |||
self.TransmitFrec, | |||
self.ReceiveFrec, | |||
self.FirstOsciFrec, | |||
self.Polarisation, | |||
self.ReceiverFiltSett, | |||
self.nModesInUse, | |||
self.DualModeIndex, | |||
self.DualModeRange, | |||
self.nDigChannels, | |||
self.SampResolution, | |||
self.nRangeGatesSamp, | |||
self.StartRangeSamp, | |||
self.PRFhz, | |||
self.Integrations, | |||
self.nDataPointsTrsf, | |||
self.nReceiveBeams, | |||
self.nSpectAverages, | |||
self.FFTwindowingInd, | |||
self.BeamAngleAzim, | |||
self.BeamAngleZen, | |||
self.AntennaCoord, | |||
self.RecPhaseCalibr, | |||
self.RecAmpCalibr, | |||
self.ReceiverGaindB) | |||
# self.size,self.nSamples, | |||
# self.nProfiles, | |||
# self.nChannels, | |||
# self.adcResolution, | |||
# self.pciDioBusWidth | |||
header = numpy.array(headerTuple,RECORD_STRUCTURE) | |||
header.tofile(fp) | |||
return 1 | |||
def get_dtype_index(numpy_dtype): | |||
index = None | |||
for i in range(len(NUMPY_DTYPE_LIST)): | |||
if numpy_dtype == NUMPY_DTYPE_LIST[i]: | |||
index = i | |||
break | |||
return index | |||
def get_numpy_dtype(index): | |||
#dtype4 = numpy.dtype([('real','<f4'),('imag','<f4')]) | |||
return NUMPY_DTYPE_LIST[index] | |||
def get_dtype_width(index): | |||
return DTYPE_WIDTH[index] |