OB.DAAC Logo
NASA Logo
Ocean Color Science Software

ocssw V2022
read_adcs.py
Go to the documentation of this file.
1 def fss_read_bytes(datain):
2  # read fine sun sensor bytes
3  import numpy as np
4  import struct
5 
6  datain = np.flip(datain,1)
7  dataout = struct.unpack('<%df'%(np.size(datain)/4),np.ascontiguousarray(datain))
8  dataout = np.flip(np.reshape(dataout,(-1,2)),1)
9 
10  return dataout
11 
12 def read_adcs_from_l1a(l1afile):
13  # Program to read ADCS data from a Hawkeye L1A file
14  # Assumes file path/name in varible l1afile
15  # Inputs:
16  # - l1afile
17  # Outputs:
18  # - ptime,sunv,mag2,gyro,rw,stime,sunxp,sunzp,sunzn,atime,quat
19  # Ported from renav_hawkeye.pro by Fred Patt.
20  # Liang Hong, 2/12/2020
21  # Liang Hong, 3/25/2020, set sun sensor zp/zn readings to 0 when readings stay unchanged
22  # Liang Hong, 4/27/2020, return empty arrays when no valid values in L1A
23 
24  import numpy as np
25  from functools import reduce
26  from hawknav.get_ncdf_object import get_ncdf_object
27 
28  group = 'navigation_data'
29 
30  # find data indices with valid time tag
31  atime = get_ncdf_object(l1afile, group, 'att_time')
32  ptime = get_ncdf_object(l1afile, group, 'processed_sensor_time')
33  stime = get_ncdf_object(l1afile, group, 'sensor_time')
34  kq = np.where(atime >= 0)
35  kp = np.where(ptime >= 0)
36  ks = np.where(stime >= 0)
37  ind_valid_ts = reduce(np.intersect1d, (kq,kp,ks))
38  if np.size(ind_valid_ts)==0:
39  # no valid readings from L1A file
40  print("No valid navigation time tags.")
41  return [],[],[],[],[],[],[],[],[],[],[]
42 
43  # Attitude quaternions
44  quat = get_ncdf_object(l1afile, group, 'att_quat')
45  atime = atime[ind_valid_ts]
46  quat = np.squeeze(quat[ind_valid_ts,:])
47 
48  # Processed sensor telemetry
49  sunv = get_ncdf_object(l1afile, group, 'sun_vector')
50  mag1 = get_ncdf_object(l1afile, group, 'mag1')
51  mag2 = get_ncdf_object(l1afile, group, 'mag2')
52  gyro = get_ncdf_object(l1afile, group, 'gyro_rates')
53  rw = get_ncdf_object(l1afile, group, 'rwheels')
54  ptime = np.squeeze(ptime[ind_valid_ts])
55  sunv = np.squeeze(sunv[ind_valid_ts,:])
56  mag2 = np.squeeze(mag2[ind_valid_ts,:])
57  gyro = np.squeeze(gyro[ind_valid_ts,:])
58  rw = np.squeeze(rw[ind_valid_ts,:])
59 
60  # FSS angles and error code
61  sensor = get_ncdf_object(l1afile, group, 'sensor_bus_telemetry')
62  stime = stime[ind_valid_ts]
63  sensor = np.squeeze(sensor[ind_valid_ts,:])
64 
65  # Extract FSS angles
66  nks = np.size(ind_valid_ts)
67  fssxp = fss_read_bytes(np.copy(sensor[:,0:8]))
68  fsszp = fss_read_bytes(np.copy(sensor[:,9:17]))
69  fsszn = fss_read_bytes(np.copy(sensor[:,18:26]))
70  fsserr = sensor[:,[8,17,26]]
71 
72  # Convert FSS angles to vectors
73  sunxp = np.zeros((nks,3))
74  tana = np.tan(np.deg2rad(fssxp[:,0]))
75  tanb = np.tan(np.deg2rad(fssxp[:,1]))
76  sunxp[:,0] = 1/np.sqrt(tana**2 + tanb**2 + 1.0)
77  sunxp[:,1] = -tanb*sunxp[:,0]
78  sunxp[:,2] = tana*sunxp[:,0]
79 
80  sunzp = np.zeros((nks,3))
81  if len(np.argwhere(np.diff(fsszp[:,0])==0))/nks<0.5:
82  # use sun sensor zp when <50% readings changing during the time, 3/25/2020
83  tana = np.tan(np.deg2rad(fsszp[:,0]))
84  tanb = np.tan(np.deg2rad(fsszp[:,1]))
85  sunzp[:,2] = 1/np.sqrt(tana**2 + tanb**2 + 1.0)
86  sunzp[:,1] = tanb*sunzp[:,2]
87  sunzp[:,0] = tana*sunzp[:,2]
88 
89  sunzn = np.zeros((nks,3))
90  if len(np.argwhere(np.diff(fsszn[:,0])==0))/nks<0.5:
91  # use sun sensor zp when <50% readings changing during the time, 3/25/2020
92  tana = np.tan(np.deg2rad(fsszn[:,0]))
93  tanb = np.tan(np.deg2rad(fsszn[:,1]))
94  sunzn[:,2] = 1/np.sqrt(tana**2 + tanb**2 + 1.0)
95  sunzn[:,1] = (tana-tanb)*sunzn[:,2]/np.sqrt(2)
96  sunzn[:,0] = (tana+tanb)*sunzn[:,2]/np.sqrt(2)
97  sunzn[:,2] = -sunzn[:,2]
98 
99  return ptime,sunv,mag2,gyro,rw,stime,sunxp,sunzp,sunzn,atime,quat
100 
def read_adcs_from_l1a(l1afile)
Definition: read_adcs.py:12
def fss_read_bytes(datain)
Definition: read_adcs.py:1