8 from sgp4.api
import jday
9 from astropy.time
import Time
10 from netCDF4
import Dataset
11 from hawknav.read_adcs
import read_adcs_from_l1a
12 from hawknav.tle2orb
import tle2orb
13 from hawknav.orb_interp
import orb_interp
14 from hawknav.l_sun
import l_sun
15 from hawknav.orb2lla
import orb2lla
16 from hawknav.ned2ecr
import ned2ecr
17 from hawknav.j2000_to_ecr
import j2000_to_ecr
18 from hawknav.propagate
import propagate
19 from hawknav.qinv
import qinv
20 from hawknav.qprod
import qprod
21 from hawknav.qmethod
import qmethod
22 from hawknav.remake_orbit_objects
import remake_orbit_objects
23 from hawknav.drop_orbit_objects
import drop_orbit_objects
24 from hawknav.write_ncdf_data_object
import write_ncdf_data_object
26 __version__ =
'0.21.1_2021-12-07'
28 def renav_hawkeye(l1afile,l1arenav,tlefile,utcpolefile=None,magbiasfix=False,verbose=False):
50 utcpolefile = os.path.join(os.environ[
'OCVARROOT'],
'modis',
'utcpole.dat')
56 print(
"reading %s" % tlefile)
57 with open(tlefile,
'r')
as tle:
58 TLEline1 = tle.readline()
59 TLEline2 = tle.readline()
60 TLEline1 = TLEline1.strip()
61 TLEline2 = TLEline2.strip()
64 print(
"Could not read TLE file.")
67 nc_fid = Dataset(l1afile,
'r')
70 print(
'Running renavigation (VER%s) on %s\n' % (__version__,l1afile))
71 ptime,sunv,mag2,gyro,rw,stime,sunxp,sunzp,sunzn,atime,quat =
read_adcs_from_l1a(l1afile)
73 print(
'Error reading input L1A file.')
78 t_start= Time(nc_fid.getncattr(
'time_coverage_start'),format=
'isot')
79 iyr =
int(t_start.yday[0:4])
80 iday =
int(t_start.yday[5:8])
82 t_start = t_start.unix - 30*60
83 t_end = Time(nc_fid.getncattr(
'time_coverage_end'),format=
'isot').unix + 30*60
87 orb =
tle2orb(TLEline1,TLEline2,t_start,t_end,t_interval)
90 if (stime[0]-ptime[0] > 0.5):
101 if (ptime[0]-stime[0] > 0.5):
102 print(
'ptime behind')
112 nsen = np.size(ptime)
113 nfss = np.size(stime)
114 nsen = np.min([nsen,nfss])
117 osec = (orb[:,0]-iday)*86400.0
118 ptime_for_orb_interp = np.copy(ptime)
121 ptime_for_orb_interp[np.where(ptime<osec[0])] += 86400
122 pi,vi,orbfl =
orb_interp(osec,orb[:,1:4],orb[:,4:7],ptime_for_orb_interp)
126 hgt[np.where(hgt>600)] = 600
127 nDecimalYear = Time(nc_fid.getncattr(
'time_coverage_start'),format=
'isot').decimalyear
130 for iRec
in range(0,nsen):
131 n2e =
ned2ecr(lon[iRec],lat[iRec])
132 geomagout = pyIGRF.igrf_value(lat[iRec],lon[iRec],hgt[iRec],nDecimalYear)[3:6]
133 bmagg.append(np.dot(geomagout,n2e).tolist())
134 magr = np.asarray(bmagg)
137 sunr,rs =
l_sun(iyr,iday,ptime)
138 sunr = np.transpose(sunr)
141 suni = np.zeros((nsen,3))
142 magi = np.zeros((nsen,3))
143 posi = np.zeros((nsen,3))
144 veli = np.zeros((nsen,3))
145 ecmat =
j2000_to_ecr(iyr*np.ones(np.shape(ptime)),iday*np.ones(np.shape(ptime)),ptime,utcpolefile)
146 suni = np.einsum(
'ij,ijk->ik',sunr,np.swapaxes(ecmat,1,2))
147 magi = np.einsum(
'ij,ijk->ik',magr,np.swapaxes(ecmat,1,2))
148 posi = np.einsum(
'ij,ijk->ik',pi,np.swapaxes(ecmat,1,2))
149 veli = np.einsum(
'ij,ijk->ik',vi,np.swapaxes(ecmat,1,2))
151 omegae = 7.29211585494e-5
152 veli[:,0] = veli[:,0] - posi[:,1]*omegae
153 veli[:,1] = veli[:,1] + posi[:,0]*omegae
161 if (t_start<1612137600)
or (magbiasfix==
True):
162 pm2 = np.array([ [0.969584, 0.022348, 0.077772],
163 [-0.024340, 0.909508, -0.003070],
164 [-0.059786, 0.082971, 0.907878] ])
165 bm2 = [ -2.154e-06, -1.405e-06, 1.664e-06 ]
166 mag2 = np.einsum(
'ij,ijk->ik',mag2,np.tile(pm2,[nsen,1,1]))
167 mag2 = mag2 - np.tile(bm2,(nsen,1))
170 bmom = [11000,12000,3500]
171 jd,fr =
jday(iyr,1,iday,0,0,0)
174 gbias = [-0.0045,-0.0042,0.0045]
177 fit = np.flipud(np.polyfit(np.arange(nsen),rwr-gyro,deg=2))
178 rwr = rwr - np.transpose(np.polynomial.polynomial.polyval(np.arange(nsen), fit))
181 cs = np.cross(sunb[1:,:],sunb[0:-1,:])
182 cr = np.cross(sunb[0:-1,:],np.cross(rwr[0:-1,:],sunb[0:-1,:]))
183 serr = np.zeros(nsen-1)+0.001
184 swt = np.zeros(nsen)+100
185 ind_err = np.argwhere(np.sum(np.square(cs-cr),1)>1e-5)
189 fit = np.flipud(np.polyfit(np.arange(nsen-1),cr-cs,deg=4,w=1/serr))
190 rwr = rwr - np.transpose(np.polynomial.polynomial.polyval(np.arange(nsen),fit))
196 magp = np.zeros((nsen,3))
197 qv = np.zeros((nsen,4))
209 magpm = np.sqrt(magp[:,0]**2+magp[:,1]**2+magp[:,2]**2)
210 magim = np.sqrt(magi[:,0]**2+magi[:,1]**2+magi[:,2]**2)
211 magp = np.divide(magp.T,magpm).T
212 magi = np.divide(magi.T,magim).T
215 vecb = np.concatenate((sunp,magp))
216 veci = np.concatenate((suni,magi))
217 wgt = np.zeros(2*nsen)
221 ind_invalid = np.argwhere(np.isnan(veci))
222 if len(ind_invalid)>0:
223 ind_invalid_row = np.unique(ind_invalid[:,0])
224 vecb = np.delete(vecb,ind_invalid_row,0)
225 veci = np.delete(veci,ind_invalid_row,0)
226 wgt = np.delete(wgt,ind_invalid_row)
228 qbb = np.zeros((nsen,4))
230 qbb[1:,:] =
qprod(np.tile(q0,(nsen-1,1)),qbp[1:,:])
233 quati = np.zeros((nsen,4))
234 quati[:,0] = qbb[:,3]
235 quati[:,1:4] = qbb[:,0:3]
239 otime = np.arange(norb) + ptime[0] - 30
240 otime_for_orb_interp = np.copy(otime)
243 otime_for_orb_interp[np.where(otime<osec[0])] += 86400
244 pi,vi,orbfl =
orb_interp(osec,orb[:,1:4],orb[:,4:7],otime_for_orb_interp)
245 ecmat =
j2000_to_ecr(iyr*np.ones(norb),iday*np.ones(norb),otime,utcpolefile)
246 posi = np.einsum(
'ij,ijk->ik',pi,np.swapaxes(ecmat,1,2))
247 veli = np.einsum(
'ij,ijk->ik',vi,np.swapaxes(ecmat,1,2))
249 omegae = 7.29211585494e-5
250 veli[:,0] = veli[:,0] - posi[:,1]*omegae
251 veli[:,1] = veli[:,1] + posi[:,0]*omegae
256 nc_fid = Dataset(l1arenav,
'a')
257 print(
'Writing updated navigation to %s\n'%l1arenav)
259 ngid = nc_fid.groups[
'navigation_data']
272 if __name__ ==
"__main__":
273 print(
"renav_hawkeye version %s"%__version__)
275 parser = argparse.ArgumentParser(prog=
'renav_hawkeye',
276 description=
'Recompute Hawkeye navigation information for a L1A file using attitude sensor data')
277 parser.add_argument(
'-v',
'--verbose', help=
'print status messages',
278 action=
'store_true',default=
False)
279 parser.add_argument(
'ifile', help=
'name of L1A file to renavigate')
280 parser.add_argument(
'ofile', help=
'output filename')
281 parser.add_argument(
'tle', help=
'TLE file')
282 parser.add_argument(
'--utcpole',
283 help=
'Polar wander file',
285 parser.add_argument(
"--magbiasfix",
286 help=
'Correct magnetometer bias',
292 args = parser.parse_args()
294 renav_hawkeye(args.ifile,args.ofile,args.tle,utcpolefile=args.utcpole,magbiasfix=args.magbiasfix,verbose=args.verbose)