OB.DAAC Logo
NASA Logo
Ocean Color Science Software

ocssw V2022
GEO_earth_location.c
Go to the documentation of this file.
1 /* file: GEO_earth_location.c */
2 
3 #include "PGS_MODIS_35251.h"
4 #include "smfio.h"
5 #include "GEO_earth.h"
6 #include "GEO_inst.h"
7 
8 /* polynomial coefficients for mirror encoder-to-angle conversion */
9 double const * poly_coef;
11 
12 /* mirr errors alpha, beta, gamma */
13 double alpha;
14 double beta;
15 double gammaa;
16 
17 /* telescope to instrument frame transformation matrix */
18 double T_tel2inst[3][3];
19 
20 /* mirror to instrument frame transformation matrix */
21 double T_mirr2inst[3][3];
22 
23 /* mirror side 1 angle range (radians) */
24 double mirr_side1_range[2];
25 
26 /* viewing vector in telescope coord */
27 /* This is derived from instrument geometry parameters */
28 double u_tel[DETECTORS_QKM][3];
29 
30 /* Earth sector start time for the scans in a granule */
32 
33 /*
34  * An array of pointers, one for each scan, to an array of mirror impulse
35  * encoder (encoder counts) values for each impulse of that scan.
36  */
38 
39 /*
40  * An array of pointers, one for each scan, to an array fo mirror impulse
41  * time (seconds) values for each impulse of that scan.
42  */
44 
45 
46 PGSt_SMF_status GEO_earth_location(
47  int const scan_number,
48  int const sample_number,
49  GEO_param_struct const * geo_params,
50  PGSt_double sample_time,
52  double ecr_sc_sample_position[MAX_PADDED][3],
53  double ecr_sc_velocity[MAX_PADDED][3],
54  double T_inst2ecr[MAX_PADDED][3][3],
55  unsigned char sample_flags[DETECTORS_QKM][MAX_PADDED],
56  double ecr_sample_position[DETECTORS_QKM][MAX_PADDED][3],
57  double terrain_sample_position[DETECTORS_QKM][MAX_PADDED][3]
58  )
59 /*
60 !C******************************************************************************
61 !Description:
62  Top-level routine in Earth Location group of the Level-1A geolocation
63  software to calculate earth location for one sample in a scan. This
64  routine calls the routines which get the instrument view vectors,
65  compute the ellipsoidal position and perform the terrain correction
66 
67 !Input Parameters:
68  scan_number the scan number
69  sample_number the sample number for the ideal band
70  geo_params Geolocation parameters struct
71  sample_time Time when sample was collected, as an offset
72  from the scan_start_time. Not used in this
73  version of the code, but will be passed on to
74  GEO_get_view_vec() in a future version.
75  l1a_data data read from the L1A file.
76  ecr_sc_sample_position interpolated sample ECR spacecraft postion
77  ecr_sc_velocity interpolated sample ECR spacecraft velocity
78 
79 !Output Parameters:
80  sample_flags terrain sample position validity flags
81  sample_time pixel sample time offset from sector start time
82  T_inst2ecr telescope to instrument frame transformation
83  matrices for each frame in a scan [INPUT]
84  ecr_sample_position ECR ground position for each sample.
85  terrain_sample_position Geodetic ground positions for each sample.
86 
87 Return Values:
88  MODIS_E_GEO_BAD_INPUT_ARG If geo_params is null.
89  MODIS_E_GEO If any subroutine fails.
90  PGS_S_SUCCESS Otherwise.
91 
92 Externally Defined:
93  From "GEO_global_arrays.h":
94  Note: all of these global variables should be defined in this module;
95  they are "externally defined" only in the sense that they have external
96  linkage.
97 
98  poly_coef polynomial coefficients for mirror
99  encoder-to-angle conversion [OUTPUT]
100  poly_degree degree of the mirror polynomial [OUTPUT]
101 
102  alpha mirror wedge angle (radians) alpha [OUTPUT]
103  beta mirror wedge angle (radians) beta [OUTPUT]
104  gammaa mirror wedge angle (radians) gammaa [OUTPUT]
105  T_tel2inst telescope to instrument frame transformation
106  matrix [OUTPUT]
107  T_mirr2inst mirror to instrument frame transformation
108  matrix [OUTPUT]
109  mirr_side1_range mirror side 1 angle range (radians) [OUTPUT]
110  scan_start_time Earth View scan start times [OUTPUT]
111  mirr_impulse_enc an array of pointers, one for each scan, to an
112  array of mirror impulse encoder (encoder
113  counts) values for each impulse of that
114  scan [OUTPUT]
115  mirr_impulse_time an array of pointers, one for each scan, to an
116  array of mirror impulse time (seconds)
117  values for each impulse of that scan [OUTPUT]
118 
119  CHAN_A "GEO_parameters.h"
120  CHAN_B "GEO_parameters.h"
121  DETECTORS_QKM "GEO_geo.h"
122  MODIS_E_GEO "PGS_MODIS_35251.h"
123  MODIS_E_GEO_BAD_INPUT_ARG "PGS_MODIS_35251.h"
124  MAX_PADDED "GEO_geo.h"
125  PGS_S_SUCCESS "PGS_SMF.h"
126  SUCCESS "GEO_basic.h"
127 
128 Called by:
129  GEO_locate_one_scan "GEO_output.h"
130 
131 Routines Called:
132  GEO_get_view_vec "GEO_inst.h"
133  GEO_ellip_position "GEO_earth.h"
134  GEO_terrain_correct "GEO_earth.h"
135  modsmf "smfio.h"
136 
137 !Revision History:
138  $Log: GEO_earth_location.c,v $
139  Revision 6.4 2013/05/23 18:30:55 jkuyper
140  Change l1a_data argument of GEO_earth_location() to be a pointer to
141  non-const, to allow initialization of mirr_impulse_enc.
142 
143  Revision 6.3 2011/02/14 21:24:44 kuyper
144  Corrected const-qualification of several pointers.
145 
146  Revision 6.2 2009/05/30 23:50:38 kuyper
147  Added global variables that were supposed to be moved to this module
148  from GEO_locate_one_scan.c.
149  Changed to take l1a_data as a parameter, and to calculate
150  scan_start_time, mirr_impulse_ang, and mirr_impulse_time from it.
151  Changed to set poly_coef.
152  Made error messages more informative.
153 
154  Revision 6.2 2009/05/30 18:29:32 kuyper
155  Added global variables that were supposed to be moved to this module
156  from GEO_locate_one_scan.c.
157  Changed to take l1a_data as a parameter, and to calculate
158  scan_start_time, mirr_impulse_ang, and mirr_impulse_time from it.
159  Made error messages more informative.
160 
161  Revision 6.1 2009/05/29 13:57:24 xgeng
162  Move definition, initialization of some global variables into this module
163  from GEO_locate_one_scan().
164  Changed sample_view_vec and ellip_sample_position from global arrays to local.
165  Changed to pass what used to be global arrays as arguments to and from
166  GEO_ellip_position(), and GEO_terrain_correct().
167  Changed to expect status code values from GEO_ellip_position() and
168  GEO_terrain_correct(), and to return a status code.
169  Cleaned up error detection and error messaging.
170  Changed MAX_SCAN_SAMPLES to MAX_PADDED.
171  The above changes match with PDL revision 6.1 and 6.2.
172  Please note that 'sample_time' and 'scan_start_time' are not currently used.
173  They are added at this time, so that in some future revision,
174  we can pass them through GEO_get_view_vec() and GEO_get_inst_mirr_normal()
175  all the way down to GOE_interp_mirr_enc().
176 
177  Xu Geng (xu.geng@saic.com)
178 
179  Revision 2.1 1997/10/21 18:16:22 kuyper
180  Returned from ClearCase
181 
182  * Revision 1.6.1.1 1997/07/21 22:20:17 kuyper
183  * Merged in out-of-sequence changes.
184  *
185  * Revision 1.6 1997/07/21 16:24:34 kuyper
186  * Baselined Version 1
187  *
188  *Parallel Development:
189  * Revision 1.7 1997/04/21 22:28:51 fhliang
190  * removed unused argument 'scan_number' (LL.112-115).
191  *
192  * Revision 1.6 1997/03/26 18:02:57 fhliang
193  * Initial revision of GEO_earth_location.c.
194  *
195  Revision 1.5 1997/02/13 19:28:56 kuyper
196  Merged seed files.
197 
198  Revision 1.4 1996/07/24 20:59:10 kuyper
199  Standardized order of #include files.
200  Declared arguments const.
201 
202  Revision 1.3 1996/07/23 22:59:14 kuyper
203  Inserted required '!' in comments.
204  Changed constants to double to avoid conversions.
205  Removed ret_val.
206 
207  Revision 1.2 1996/07/18 15:58:00 kuyper
208  Included self-checking header file, and other needed header files.
209 
210 
211  4/25/95
212  Ruiming Chen (rchen@ltpmail.gsfc.nasa.gov)
213  Finished coding.
214 
215  7/3/95
216  Tracey W. Holmes (holmes@modis-xl.gsfc.nasa.gov)
217  Added SDP error messages.
218 
219  10/10/95
220  Tracey W. Holmes
221  Added debug option.
222 
223 !Team-unique Header:
224  This software is developed by the MODIS Science Data Support
225  Team for the National Aeronautics and Space Administration,
226  Goddard Space Flight Center, under contract NAS5-32373.
227 
228 !END*************************************************************************
229 */
230 {
231  int i, j, det;
232  double u_inst[DETECTORS_QKM][3] = {0.0};
233 
234  typedef double padded3_t[MAX_PADDED][3];
235  static padded3_t *sample_view_vec;
236  static padded3_t *ellip_sample_position;
237  static int firstRun = 1;
238  if(firstRun) {
239  firstRun = 0;
240  sample_view_vec = (padded3_t*) calloc(DETECTORS_QKM, sizeof(padded3_t));
241  ellip_sample_position = (padded3_t*) calloc(DETECTORS_QKM, sizeof(padded3_t));
242  }
243 
244  char msgbuf[PGS_SMF_MAX_MSGBUF_SIZE];
245  char filefunc[] = __FILE__ ", GEO_earth_location";
246 
247  if (geo_params == NULL) {
248  modsmf(MODIS_E_BAD_INPUT_ARG, "geo_params is null", filefunc);
249  return MODIS_E_BAD_INPUT_ARG;
250  }
251 
252  if (poly_degree < geo_params->poly_degree) {
253  alpha = geo_params->mirror_model.alpha;
254  beta = geo_params->mirror_model.beta;
255  gammaa = geo_params->mirror_model.gammaa;
256  mirr_side1_range[0] = geo_params->mirror_model.mirr_side1_range[0];
257  mirr_side1_range[1] = geo_params->mirror_model.mirr_side1_range[1];
258  for(i = 0; i < 3; i++)
259  for(j = 0; j < 3; j++)
260  {
261  T_mirr2inst[i][j] = geo_params->coord_trans.T_mirr2inst[i][j];
262  T_tel2inst[i][j] = geo_params->coord_trans.T_tel2inst[i][j];
263  }
264  for (det = 0; det < geo_params->num_detectors; det++)
265  {
266  for (i = 0; i < 3; i++)
267  u_tel[det][i] = geo_params->u_tel[det][i];
268  }
269  poly_degree = geo_params->poly_degree;
270  }
271  scan_start_time[scan_number] = l1a_data->frame_data[scan_number].EV_start;
272  mirr_impulse_enc[scan_number] =
273  l1a_data->mirr_data[scan_number].mirr_impulse_enc;
274  mirr_impulse_time[scan_number] =
275  l1a_data->mirr_data[scan_number].mirr_impulse_time;
276  if(l1a_data->mirr_data[scan_number].mirr_chan == CHAN_A)
277  poly_coef = geo_params->poly_coef[CHAN_A];
278  else
279  poly_coef = geo_params->poly_coef[CHAN_B];
280 
281  /* get view vector */
282  if (GEO_get_view_vec(scan_number, sample_number, geo_params->num_detectors,
283  u_inst) != SUCCESS)
284  {
285  /* call SDP function to report error */
286  sprintf(msgbuf, "GEO_get_view_vec(%d, %d, %d)",
287  scan_number, sample_number, geo_params->num_detectors);
288  modsmf(MODIS_E_GEO, msgbuf, filefunc);
289  return MODIS_E_GEO;
290  }
291 
292  /* get ellipsoid position */
293  if (GEO_ellip_position(scan_number, sample_number, geo_params->num_detectors,
294  u_inst, ecr_sc_sample_position, ecr_sc_velocity, T_inst2ecr,
295  ecr_sample_position, ellip_sample_position, sample_flags, sample_view_vec)
296  != PGS_S_SUCCESS)
297  {
298  /* call SDP function to report error */
299  sprintf(msgbuf, "GEO_ellip_position(%d, %d, %d)",
300  scan_number, sample_number, geo_params->num_detectors);
301  modsmf(MODIS_E_GEO, msgbuf, filefunc);
302  return MODIS_E_GEO;
303  }
304 
305  /* get terrain corrected position */
306  if (GEO_terrain_correct(sample_number, geo_params->num_detectors,
307  sample_view_vec, ecr_sample_position, ellip_sample_position, sample_flags,
308  terrain_sample_position ) != PGS_S_SUCCESS)
309  {
310  /* call SDP function to report error */
311  sprintf(msgbuf, "GEO_terrain_correct(%d, %d)",
312  sample_number, geo_params->num_detectors);
313  modsmf(MODIS_E_GEO, msgbuf, filefunc);
314  return MODIS_E_GEO;
315  }
316 
317  return PGS_S_SUCCESS;
318 }
319 
double gammaa
#define SUCCESS
Definition: ObpgReadGrid.h:15
int j
Definition: decode_rs.h:73
double * mirr_impulse_time[MAX_SCAN_NUMBER]
double T_mirr2inst[3][3]
#define NULL
Definition: decode_rs.h:63
#define MODIS_E_BAD_INPUT_ARG
internal_coord_trans_struct coord_trans
int16_t * l1a_data
Definition: l1a_seawifs.c:84
#define MAX_PADDED
Definition: GEO_geo.h:84
const double * poly_coef
double u_tel[DETECTORS_QKM][3]
#define MODIS_E_GEO
PGSt_SMF_status GEO_terrain_correct(int const sample_number, int const num_detectors, double sample_view_vec[][MAX_PADDED][3], double ecr_sample_position[][MAX_PADDED][3], double ellip_sample_position[][MAX_PADDED][3], unsigned char sample_flags[][MAX_PADDED], double terrain_sample_position[][MAX_PADDED][3])
#define CHAN_A
double poly_coef[ELEC_SIDES][MAX_POLY_DEGREE+1]
double alpha
double * sample_time
PGSt_SMF_status GEO_earth_location(int const scan_number, int const sample_number, GEO_param_struct const *geo_params, PGSt_double sample_time, l1a_data_struct *l1a_data, double ecr_sc_sample_position[MAX_PADDED][3], double ecr_sc_velocity[MAX_PADDED][3], double T_inst2ecr[MAX_PADDED][3][3], unsigned char sample_flags[DETECTORS_QKM][MAX_PADDED], double ecr_sample_position[DETECTORS_QKM][MAX_PADDED][3], double terrain_sample_position[DETECTORS_QKM][MAX_PADDED][3])
double T_tel2inst[3][3]
#define CHAN_B
mirror_model_struct mirror_model
PGSt_SMF_status GEO_ellip_position(int const scan_number, int const sample_number, int const num_detectors, double u_inst[][3], double ecr_sc_sample_position[][3], double ecr_sc_velocity[][3], double T_inst2ecr[][3][3], double ecr_sample_position[][MAX_PADDED][3], double ellip_sample_position[][MAX_PADDED][3], unsigned char sample_flags[][MAX_PADDED], double sample_view_vec[][MAX_PADDED][3])
const int MAX_SCAN_NUMBER
double beta
double scan_start_time[MAX_SCAN_NUMBER]
int GEO_get_view_vec(const int scan_number, const int sample_number, const int num_detectors, double u_inst[MAX_DETECTORS][3])
double mirr_side1_range[2]
double u_tel[DETECTORS_QKM][3]
#define DETECTORS_QKM
Definition: GEO_geo.h:87
int i
Definition: decode_rs.h:71
double * mirr_impulse_enc[MAX_SCAN_NUMBER]
int poly_degree