3 Created on Nov 19, 2015
7 from netCDF4
import Dataset
9 def proc_hico(ifile,earth_orient_file,leap_sec_file,boresight,nc_grp,calib_grp):
19 lonHemi = {1:
'E',0:
'W'}
20 latHemi = {1:
'N',0:
'S'}
21 direction = {1:
'ascending',0:
'descending'}
22 byteorder = {
'little':0,
'big':1}
29 ocvarroot = os.environ[
'OCVARROOT']
31 print(
"OCSSW environement variable OCVARROOT not set.")
32 print(
"Typically it is set to $OCSSW/run/var.")
37 bs[0] = boresight[0]*deg2Rad
38 bs[1] = boresight[1]*deg2Rad
39 bs[2] = boresight[2]*deg2Rad
40 r_hico_bs = bore.bore_sight(bs)
42 (quat_info, quat, pvq_data) = rquat.read_pos_vel_quat(ifile)
43 nsamples = np.int(quat_info[
'Requested number of pixels'])
49 filein =
"{}/hico/{}".format(ocvarroot,
'nutation.dat')
51 nut_data = astreduc.initReduc(filein)
52 astrodate = astreduc.HicoSec2Date(pvq_data[
'SecondsSinceEpoch'][0])
54 yyyy = astrodate.yyyy % 100
57 pmx,pmy,dut1,loda = astreduc.getEDFData(earth_orient_file,yyyy,astrodate.mm,astrodate.dd)
60 print(
"Earth Data File does not have year={},month={},day={}".format(astrodate.yyyy,astrodate.mm,astrodate.dd))
65 lsdat = astreduc.getLSData(leap_sec_file,astrodate.yyyy,astrodate.mm,astrodate.dd)
68 print(
"Leap Sec File does not have year={},month={},day={}".format(astrodate.yyyy,astrodate.mm,astrodate.dd))
78 r_hico_to_iss = np.diagflat([-1]*2+[1])
81 r_hico_to_iss = np.dot(r_hico_to_iss,r_hico_bs)
88 if quat_info[
'ISS orientation'] ==
'+XVV':
92 theta = np.zeros(nsamples)
94 for i
in range(0,nsamples):
95 frac = imult*(i-255.5)/255.5
96 theta[i] = ( -3.487 + 0.035 * frac**2)*frac
98 theta = (theta + theta_stowed +
float(quat_info[
'Theta (degrees from stowed position)']))*deg2Rad
105 svec = np.zeros((3,nsamples))
108 svec[1,:] = -np.sin(theta[:])
109 svec[2,:] = np.cos(theta[:])
111 pm = astreduc.polarm(pmx,pmy)
115 r_iss = np.array((3),dtype=float)
116 q_iss = np.array((4),dtype=float)
117 fout = quat_info[
'Expected Lon/Lat/View angle filename']
118 fheader = fout.split(
'.bil')[0] +
'.hdr'
120 lines = pvq_data[
'SecondsSinceEpoch'].size
123 hicoHeader = hicoLonLatHdr(filename=fheader, \
126 description=
'HICO geometry file, with calculated positions, and solar & view geometry, on the ground', \
127 sensor_type=
'HICO-ISS' \
129 hicoHeader.set_variable(
'data type',5)
130 hicoHeader.set_variable(
'interleave',
'bil')
131 hicoHeader.set_variable(
'wavelength units',
'{ degrees, degrees, degrees, degrees, degrees, degrees }')
132 hicoHeader.set_variable(
'band names',
'{ longitude, latitude, view zenith, view azimuth, sol zenith, sol azimuth }')
133 hicoHeader.set_variable(
'byte order',byteorder[sys.byteorder])
134 hicoHeader.set_variable(
'geometry_deltaUT1_s',dut1)
135 hicoHeader.set_variable(
'geometry_deltaT_s',lsdat)
136 hicoHeader.set_variable(
'geometry_xp_rad',pmx)
137 hicoHeader.set_variable(
'geometry_yp_rad',pmy)
138 hicoHeader.set_variable(
'geometry_LOD',loda)
139 hicoHeader.set_variable(
'geometry_bore_sight_params',
'{ ' +
', '.join(
str(v)
for v
in bs) +
' }')
141 for i
in range(0,lines):
144 r_iss = np.multiply([pvq_data[
'ISSPOSX'][i],pvq_data[
'ISSPOSY'][i],pvq_data[
'ISSPOSZ'][i] ],0.3048e0)
145 q_iss = [ pvq_data[
'ISSQS'][i],pvq_data[
'ISSQX'][i],pvq_data[
'ISSQY'][i],pvq_data[
'ISSQZ'][i] ]
146 rot_body = astreduc.quat_to_rot(q_iss)
147 astrodate = astreduc.HicoSec2Date(pvq_data[
'SecondsSinceEpoch'][i])
148 hico_jdate =
astreduc.UT2time(astrodate.yyyy,astrodate.mm,astrodate.dd,astrodate.hour,astrodate.min,astrodate.sec,dut1,lsdat)
150 prec = astreduc.precession(hico_jdate.ttdb)
151 DeltaPsi, TrueEps, MeanEps, Omega, nut = astreduc.nutation(hico_jdate.ttdb,nut_data)
152 st,stdot,OmegaEarth = astreduc.sidereal(hico_jdate.jdut1,DeltaPsi,TrueEps,Omega,loda,2)
154 t_eci_to_ecef=np.dot(pm,np.dot(st,np.dot(nut,prec)))
156 t_hico_to_ecef=np.dot(t_eci_to_ecef,np.dot(rot_body,r_hico_to_iss))
158 r_ecef=np.dot(t_eci_to_ecef,r_iss)
161 v_ecef=np.dot(t_hico_to_ecef,svec)
162 llh,view_zen,view_az = astreduc.wgs84_intercept(r_ecef,v_ecef)
164 sol_zen_az=rad2Deg*astreduc.solar_geometry(astrodate.yyyy,astrodate.mm,astrodate.dd,astrodate.hour,astrodate.min,astrodate.sec,llh[1,:],-llh[0,:])
166 lon_out = np.array(llh[0,:])
167 lat_out = np.array(llh[1,:])
168 viewzen = np.array(view_zen,dtype=
'f8')
169 viewaz = np.array((360.0 +view_az) % 360.0,dtype=
'f8')
170 solarzen = np.array(sol_zen_az[0,:],dtype=
'f8')
171 solaraz = np.array(sol_zen_az[1,:],dtype=
'f8')
172 nc_grp[
'sensor_zenith'][i] = viewzen
173 nc_grp[
'sensor_azimuth'][i] = viewaz
174 nc_grp[
'solar_zenith'][i] = solarzen
175 nc_grp[
'solar_azimuth'][i] = solaraz
176 nc_grp[
'longitude'][i] = lon_out
177 nc_grp[
'latitude'][i] = lat_out
178 bilout = np.concatenate((lon_out,lat_out))
179 bilout = np.concatenate((bilout,viewzen))
180 bilout = np.concatenate((bilout,viewaz))
181 bilout = np.concatenate((bilout,solarzen))
182 bilout = np.concatenate((bilout,solaraz ))
183 myfmt=
'd'*len(bilout)
184 binout = struct.pack(myfmt,*bilout)
190 hicoHeader.set_variable(
'date',
'{ ' +
str(astrodate.yyyy)+
','+
str(astrodate.mm)+
','+
str(astrodate.dd) +
' }')
191 hicoHeader.set_variable(
'time',
'{ ' +
str(astrodate.hour)+
','+
str(astrodate.min)+
','+
str(astrodate.sec) +
' }')
192 hicoHeader.set_variable(
'image_center_long',
'{ ' +
', '.join(
str(v)
for v
in frac2DegMinSec(np.abs(lon_out[254]),0.,0.)) +
' }')
193 hicoHeader.set_variable(
'image_center_lat',
'{ ' +
', '.join(
str(v)
for v
in frac2DegMinSec(np.abs(lat_out[254]),0.,0.)) +
' }')
194 hicoHeader.set_variable(
'image_center_long_hem', lonHemi[(lon_out[254]>=0)])
195 hicoHeader.set_variable(
'image_center_lat_hem', latHemi[(lat_out[254]>=0)])
196 hicoHeader.set_variable(
'image_center_zenith_ang',
'{ ' +
', '.join(
str(v)
for v
in frac2DegMinSec((viewzen[254]+viewzen[255])/2,0.,0.)) +
' }')
197 hicoHeader.set_variable(
'image_center_azimuth_ang',
'{ ' +
', '.join(
str(v)
for v
in frac2DegMinSec((viewaz[254]+viewaz[255])/2,0.,0.)) +
' }')
198 hicoHeader.set_variable(
'geometry_ISS_Z_direction',direction[(pvq_data[
'ISSVELZ'][i]>=0)])
199 r_iss_new = np.tile(r_iss[np.newaxis],1).T
200 llh = astreduc.ecef2latlon(r_iss_new)
201 hicoHeader.set_variable(
'sensor_altitude',llh[2,0]/1000.)
208 hicoHeader.createHistory(quat_info)
209 hicoHeader.writeHicoENVIHeaderFile()
211 calib_grp.hico_orientation_from_quaternion = quat_info[
'ISS orientation']
213 if __name__ ==
'__main__':
216 parser = argparse.ArgumentParser(formatter_class=argparse.RawTextHelpFormatter, description=
'''\
217 Generate a HICO geometry file.
220 parser.add_argument(
'-ifile', nargs=1, type=str, help=
' iss*pos_vel_quat.csv input file (Must be a CSV file) ')
221 parser.add_argument(
'-lfile', nargs=1, type=str, help=
' leapsec file ')
222 parser.add_argument(
'-efile', nargs=1, type=str, help=
' earth-orient file ')
223 parser.add_argument(
'-boresight', nargs=3, type=float, default=([0, 0, 0]), help=(
'Process Bore Sight Parameters'))
225 args = parser.parse_args(
'-ifile iss.2013067.0308.063527.L0.12933.20130308205743.hico_pos_vel_quat.csv -efile /home/rhealy/ocsswn/run/var/hico/finals.data -lfile /home/rhealy/ocsswn/run/var/modis/leapsec.dat -boresight -0.9957 0.0268 -0.0128'.split())
227 ifile =
''.join(args.ifile)
228 earth_orient_file =
''.join(args.efile)
229 leap_sec_file =
''.join(args.lfile)
230 boresight = args.boresight
231 rootgrp = Dataset(
'test_hico.nc',
'w')
232 rootgrp.createDimension(
'scan_lines', 2000)
233 rootgrp.createDimension(
'samples', 512)
237 navigation = rootgrp.createGroup(
"navigation")
239 senz = navigation.createVariable(
'sensor_zenith',
'f4',(
'scan_lines',
'samples',))
240 solz = navigation.createVariable(
'solar_zenith',
'f4',(
'scan_lines',
'samples',))
241 sena = navigation.createVariable(
'sensor_azimuth',
'f4',(
'scan_lines',
'samples',))
242 sola = navigation.createVariable(
'solar_azimuth',
'f4',(
'scan_lines',
'samples',))
243 lon = navigation.createVariable(
'longitude',
'f4',(
'scan_lines',
'samples',))
244 lat = navigation.createVariable(
'latitude',
'f4',(
'scan_lines',
'samples',))
245 senz.units =
'degrees'
248 senz.long_name =
'sensor zenith'
249 solz.units =
'degrees'
251 solz.long_name =
'solar zenith'
253 sena.units =
'degrees'
254 sena.valid_min = -180
256 sena.long_name =
'sensor azimuth'
257 sola.units =
'degrees'
258 sola.valid_min = -180
260 sola.long_name =
'solar azimuth'
261 lon.units =
'degrees'
264 lon.long_name =
'longitude'
265 lat.units =
'degrees'
268 lat.long_name =
'latitude'
270 metadata = rootgrp.createGroup(
"metadata")
271 hico = metadata.createGroup(
"HICO")
272 calibration = hico.createGroup(
"Calibration")
273 proc_hico(ifile,earth_orient_file,leap_sec_file,boresight,navigation,calibration)