3 Created on Tue Feb 3 14:01:27 2015
4 Reads Hico L0 bil file.
5 Header (first 256 bytes) parsed into header dictionary.
12 import datetime
as dtime
13 from math
import sqrt, atan, atan2, pi
20 def __init__(self, l0FileName, parentLoggerName):
24 self.
logger = logging.getLogger(
'%s.HicoL0Reader' % parentLoggerName)
25 with open(l0FileName,
'rb')
as fh:
30 def __BinaryCodedDec2Int(x):
31 return((x & 0xf0) >> 4) * 10 + (x & 0x0f)
33 def __HicoDateTime(self):
34 def __timeWrapAround(*args):
35 hr, mn, secs = (arg
for arg
in args)
47 year = self.
header[
'FFyearMSB'] * 100 + self.
header[
'FFyearLSB']
48 centerDate.append(year)
50 centerDate.append(self.
header[
'FFmonth'])
52 centerDate.append(self.
header[
'FFday'])
54 centerTime.append(self.
header[
'FFhours'])
56 centerTime.append(self.
header[
'FFmin'])
60 LFpps_ = self.
header[
'LFpps']
62 LFpps_ = (self.
header[
'LFpps'] + 2**16)
63 time_imageInt = LFpps_ + self.
header[
'LFppsSub'] * 16.762e-6 - \
64 (self.
header[
'FFpps'] + self.
header[
'FFppsSub'] * 16.762e-6)
67 secs = self.
header[
'FFsec'] + \
68 ((
int(self.
header[
'Word08'] & 0x0f) << 16) +
69 int(self.
header[
'FFsubLSB'])) * 1.0e-6 + 0.5 * time_imageInt
70 centerTime.append(secs)
71 startDate = centerDate[:]
72 endDate = centerDate[:]
73 startTime = centerTime[:]
74 endTime = centerTime[:]
75 startTime[2] -= 0.5 * time_imageInt
76 endTime[2] += 0.5 * time_imageInt
77 startTime = __timeWrapAround(*startTime)
78 endTime = __timeWrapAround(*endTime)
80 tempDate = dtime.date(centerDate[0], centerDate[1], centerDate[2])
81 iday = tempDate.timetuple().tm_yday
82 fhr = centerTime[0] + (centerTime[1] + centerTime[2] / 60) / 60
83 resDict = {
'startTime': startTime,
'centerTime': centerTime,
84 'endTime': endTime,
'startDate': startDate,
'centerDate': centerDate,
85 'endDate': endDate,
'iday': iday,
'fhr': fhr}
86 tot_time = time.time() - t_start
87 self.
logger.debug(
'time taken: %f' % tot_time)
99 print(
"!!-> Incorrect arg. # @ LatLonH")
102 recFlat = 1 / 298.257223563
103 seminax = esa_m * (1 - recFlat)
104 fEcc_2 = 2 * recFlat * (1 - recFlat)
105 sEcc_2 = recFlat * (2 - recFlat) / ((1 - recFlat) ** 2)
108 ee2 = esa_m**2 - seminax**2
109 ff = 54 * seminax ** 2 * z**2
110 g = r2 + (1 - fEcc_2) * z ** 2 - fEcc_2*ee2
111 c = (fEcc_2**2 * ff * r2) / (g**3)
112 s = 1.0 + c + sqrt(c * (c + 2)) ** (1.0/3.0)
113 p = ff / (2.0 * (s + 1.0 / (s) + 1.0)**2 * g**2)
114 q = sqrt(1.0 + 2 * fEcc_2**2 * p)
115 ro = -(fEcc_2*p*r) / (1+q) + sqrt((esa_m**2 / 2.0) * (1+1.0/q) -
116 ((1-fEcc_2) * p * z**2) / (q * (1+q)) - p*r2/2.0)
117 tmp = (r - fEcc_2 * ro)**2
119 v = sqrt(tmp+(1-fEcc_2)*z**2)
120 z0 = (seminax**2 * z) / (esa_m * v)
121 h = u*(1 - seminax ** 2 / (esa_m * v))
122 phi = atan((z + sEcc_2*z0)/r)*180.0/pi
123 lambd = atan2(y, x) * 180.0 / pi
124 returnList = [phi, lambd, h]
127 def __ParseFillHeaderDict(self, fHandle):
129 Goes through 256-byte embedded HICO header data.
130 Note that header is big-endian while data is little-endian
132 t_start = time.time()
133 keys = [
'Sync',
'Len',
'FFpre',
'FFyearMSB',
'FFyearLSB',
'FFmonth',
'FFday',
134 'FFhours',
'FFmin',
'FFsec',
'Word08',
'FFsubLSB',
'FFpps',
'FFppsSub',
135 'LFpps',
'LFppsSub',
'roiw',
'roih',
'roix',
'roiy',
'hbin',
'vbin',
136 'ROport',
'ROspeed',
'IcuSwVersion',
'CamClearMode',
'TotalFrames',
137 'Dark1',
'Scene',
'Dark2',
'ID',
'ExpTime']
138 values = struct.unpack(
'>4sL8b10H6b5HL', fHandle.read(56))
139 d1 = dict(zip(keys, values))
140 if d1[
'Sync'] != b
'HICO':
141 sys.exit(
"File is not L0. Exiting...")
142 keys2 = [
'FFpos',
'FFvel',
'FFquat']
143 FFpos = np.fromfile(fHandle, dtype=
'>f4', count=3)
144 FFvel = np.fromfile(fHandle, dtype=
'>f4', count=3)
145 FFquat = np.fromfile(fHandle, dtype=
'>f4', count=4)
147 keys3 = [
'FFgncSec',
'FFgncSubSec',
'FFgncQual',
'TotalErr']
148 values3 = struct.unpack(
'>L2bH', fHandle.read(8))
150 keys4 = [
'LFpos',
'LFvel',
'LFquat']
151 LFpos = np.fromfile(fHandle, dtype=
'>f4', count=3)
152 LFvel = np.fromfile(fHandle, dtype=
'>f4', count=3)
153 LFquat = np.fromfile(fHandle, dtype=
'>f4', count=4)
155 keys5 = [
'LFgncSec',
'LFgncSubSec',
'LFgncQual',
'EventFlags',
'Dark1Offset',
156 'SceneOffset',
'Dark2Offset',
'Again',
't_on',
't_dark',
't_obs',
't_ang',
157 'TriggerCount',
'EMgain',
'Dark1Tel',
'Dark1Pos',
'Dark1TriggerCount',
158 'SceneTel',
'ScenePos',
'SceneTriggerCount',
'Dark2Tel',
'Dark2Pos',
159 'Dark2TriggerCount',
't_motor',
'Spare100',
'Spare101',
'Spare102',
161 values5 = struct.unpack(
'>L2bH4L7Hh2Hh2Hh6H', fHandle.read(64))
164 Errors = np.fromfile(fHandle, dtype=
'>i2', count=24)
165 d2 = dict(zip(keys2, (FFpos, FFvel, FFquat)))
166 d3 = dict(zip(keys3, values3))
167 d4 = dict(zip(keys4, (LFpos, LFvel, LFquat)))
168 d5 = dict(zip(keys5, values5))
169 d6 = dict(zip(keys6, Errors))
186 tot_time = time.time() - t_start
187 self.
logger.debug(
'time taken: %f' % tot_time)
190 def __ParseFillDataDict(self, fHandle):
192 t_start = time.time()
203 pic0 = np.reshape(np.fromfile(fHandle, dtype=
'<i2', count=count),
205 self.
data = {
"ns": ns,
"nb": nb,
"nl": nl,
"offset": 2561,
206 "file_type":
'ENVI Standard',
"data_type": 12,
"interleave":
'bil',
207 "sensor_type": self.
header[
'Sync'],
"byte order": 0,
208 "exposure_time": self.
header[
'TriggerCount'] * 1.117460459,
212 "start_date": dtDict[
'startDate'],
"start_time": dtDict[
'startTime'],
213 "center_date": dtDict[
'centerDate'],
"center_time": dtDict[
'centerTime'],
214 "end_date": dtDict[
'endDate'],
"end_time": dtDict[
'endTime'],
215 "yearDay": dtDict[
'iday'],
"floatHour": dtDict[
'fhr'],
216 "ScenePointingAngle": (self.
header[
'ScenePos'] + 395) * 0.004,
217 "FFVelMag": sqrt(sum((self.
header[
'FFvel'] * m2ft - 3) ** 2)),
218 "LFVelMag": sqrt(sum((self.
header[
'LFvel'] * m2ft - 3) ** 2)),
219 "FFLatLonH": ffLatLonH,
220 "LFLatLonH": lfLatLonH,
221 "FFquat": self.
header[
"FFquat"],
222 "LFquat": self.
header[
"LFquat"],
223 "Dark1Pos": self.
header[
"Dark1Pos"],
224 "Dark2Pos": self.
header[
"Dark2Pos"],
227 tot_time = time.time() - t_start
228 self.
logger.debug(
'time taken: %f' % tot_time)