OB.DAAC Logo
NASA Logo
Ocean Color Science Software

ocssw V2022
emeta_exploit.c
Go to the documentation of this file.
1 /*
2  * Name: emeta_exploit.c
3  *
4  * Purpose:
5  * Source file containing the functions that use the enhanced metadata to calculate
6  * viewing and solar illumination angles. These functions operate on the EMETA data
7  * type defined in "emeta.h".
8  */
9 #include <stdio.h>
10 #include <stdlib.h>
11 #include <string.h>
12 #include <math.h>
13 #include "ias_logging.h"
14 #include "ias_odl.h" /* ODL access routines for reading metadata */
15 #include "emeta_exploit.h" /* Definition of EMETA structure and
16  function prototypes. */
17 #include "emeta_geometry.h" /* emeta_calc_vectors prototype */
18 
19 #define MAX_FIELD_NAME 128 /* Maximum number of characters in an ODL
20  field name in the enhanced metadata file */
21 
22 int emeta_read(
23  EMETA *emeta, /* Enhanced metadata structure to load */
24  const char *emeta_filename ) /* Input file name to read */
25 {
26  IAS_OBJ_DESC *emeta_odl; /* Enhanced metadata ODL object */
27  int i; /* Loop index */
28 
29  /* Open file */
30  emeta_odl = ias_odl_read_tree( emeta_filename );
31  if ( emeta_odl == NULL )
32  {
33  IAS_LOG_ERROR("Opening input enhanced metadata file %s.", emeta_filename);
34  return(ERROR);
35  }
36 
37  /* Read data */
38  /* File information group */
39  if ( emeta_read_file_header( emeta, emeta_odl ) != SUCCESS )
40  {
41  IAS_LOG_ERROR("Reading FILE_HEADER group from %s.", emeta_filename);
42  ias_odl_free_tree( emeta_odl );
43  return(ERROR);
44  }
45 
46  /* Projection information group */
47  if ( emeta_read_projection( &emeta->projection, emeta_odl ) != SUCCESS )
48  {
49  IAS_LOG_ERROR("Reading PROJECTION group from %s.", emeta_filename);
50  ias_odl_free_tree( emeta_odl );
51  return(ERROR);
52  }
53 
54  /* Ephemeris data group and solar vector data group */
55  if ( emeta_read_ephemeris( emeta, emeta_odl ) != SUCCESS )
56  {
57  IAS_LOG_ERROR("Reading EPHEMERIS group from %s.", emeta_filename);
58  ias_odl_free_tree( emeta_odl );
59  return(ERROR);
60  }
61 
62  /* Band information */
63  for ( i=0; i<emeta->num_band; i++ )
64  {
65  if ( emeta_read_band_meta( &emeta->band_emeta[i], emeta_odl ) != SUCCESS )
66  {
67  IAS_LOG_ERROR("Reading band metadata for index %d from %s.", i, emeta_filename);
68  ias_odl_free_tree( emeta_odl );
69  return(ERROR);
70  }
71  }
72 
73  /* Release the ODL structure */
74  ias_odl_free_tree( emeta_odl );
75 
76  return(SUCCESS);
77 }
78 
80  EMETA *emeta, /* Enhanced metadata structure to load */
81  IAS_OBJ_DESC *emeta_odl ) /* Enhanced metadata ODL object */
82 {
83  int i; /* Loop index */
84  int band_list[IAS_MAX_NBANDS]; /* Local array for loading band numbers */
85  int count; /* Counter for ODL read routines */
86 
87  /* Read data */
88  /* File information fields */
89 // if ( ias_odl_get_field( &emeta->wrs_path, sizeof(int), IAS_ODL_Int, emeta_odl,
90 // "FILE_HEADER", "WRS_PATH", &count ) != SUCCESS )
91 // {
92 // IAS_LOG_ERROR("Reading WRS_PATH from FILE_HEADER group.");
93 // return(ERROR);
94 // }
95 // if ( ias_odl_get_field( &emeta->wrs_row, sizeof(int), IAS_ODL_Int, emeta_odl,
96 // "FILE_HEADER", "WRS_ROW", &count ) != SUCCESS )
97 // {
98 // IAS_LOG_ERROR("Reading WRS_ROW from FILE_HEADER group.");
99 // return(ERROR);
100 // }
101  if ( ias_odl_get_field( &emeta->num_band, sizeof(int), IAS_ODL_Int, emeta_odl,
102  "FILE_HEADER", "NUMBER_OF_BANDS", &count ) != SUCCESS )
103  {
104  IAS_LOG_ERROR("Reading NUMBER_OF_BANDS from FILE_HEADER group.");
105  return(ERROR);
106  }
107  if ( ias_odl_get_field( band_list, emeta->num_band*sizeof(int), IAS_ODL_Int, emeta_odl,
108  "FILE_HEADER", "BAND_LIST", &count ) != SUCCESS ||
109  count != emeta->num_band )
110  {
111  IAS_LOG_ERROR("Reading BAND_LIST from FILE_HEADER group.");
112  return(ERROR);
113  }
114  for ( i=0; i<emeta->num_band; i++ ) emeta->band_emeta[i].band = band_list[i];
115 
116  return(SUCCESS);
117 }
118 
120  EMETA_SCENE_PROJ *projection, /* Projection structure to load */
121  IAS_OBJ_DESC *emeta_odl ) /* Enhanced metadata ODL object */
122 {
123  double coords[2]; /* Local array for loading coordinate pairs */
124  int count; /* Counter for ODL read routines */
125  char field_name[MAX_FIELD_NAME];
126 
127  /* Read data */
128  /* Projection information group */
129  if ( ias_odl_get_field( coords, 2*sizeof(double), IAS_ODL_Double, emeta_odl,
130  "PROJECTION", "ELLIPSOID_AXES", &count ) != SUCCESS )
131  {
132  IAS_LOG_ERROR("Reading ELLIPSOID_AXES from PROJECTION group.");
133  return(ERROR);
134  }
135  projection->wgs84_major_axis = coords[0];
136  projection->wgs84_minor_axis = coords[1];
137  if ( ias_odl_get_field( &projection->code, sizeof(int), IAS_ODL_Int, emeta_odl,
138  "PROJECTION", "PROJECTION_CODE", &count ) != SUCCESS )
139  {
140  if ( ias_odl_get_field( field_name, sizeof(field_name), IAS_ODL_String, emeta_odl,
141  "PROJECTION", "MAP_PROJECTION", &count ) != SUCCESS )
142  {
143  IAS_LOG_ERROR("Reading MAP_PROJECTION from PROJECTION group.");
144  return(ERROR);
145  }
146  if(strcmp(field_name, "UTM") == 0) {
147  projection->code = 1;
148  } else {
149  projection->code = 0;
150  }
151  }
152  if ( ias_odl_get_field( projection->units, sizeof(projection->units), IAS_ODL_String, emeta_odl,
153  "PROJECTION", "PROJECTION_UNITS", &count ) != SUCCESS )
154  {
155  IAS_LOG_ERROR("Reading PROJECTION_UNITS from PROJECTION group.");
156  return(ERROR);
157  }
158  if ( ias_odl_get_field( projection->datum, sizeof(projection->datum), IAS_ODL_String, emeta_odl,
159  "PROJECTION", "PROJECTION_DATUM", &count ) != SUCCESS )
160  {
161  if ( ias_odl_get_field( projection->datum, sizeof(projection->datum), IAS_ODL_String, emeta_odl,
162  "PROJECTION", "DATUM", &count ) != SUCCESS )
163  {
164  IAS_LOG_ERROR("Reading DATUM from PROJECTION group.");
165  return(ERROR);
166  }
167  }
168 // if ( ias_odl_get_field( &projection->spheroid, sizeof(int), IAS_ODL_Int, emeta_odl,
169 // "PROJECTION", "PROJECTION_SPHEROID", &count ) != SUCCESS )
170 // {
171 // if ( ias_odl_get_field( &projection->spheroid, sizeof(int), IAS_ODL_Int, emeta_odl,
172 // "PROJECTION", "ELLIPSOID", &count ) != SUCCESS )
173 // {
174 // IAS_LOG_ERROR("Reading ELLIPSOID from PROJECTION group.");
175 // return(ERROR);
176 // }
177 // }
178  if ( ias_odl_get_field( &projection->zone, sizeof(int), IAS_ODL_Int, emeta_odl,
179  "PROJECTION", "PROJECTION_ZONE", &count ) != SUCCESS )
180  {
181  if ( ias_odl_get_field( &projection->zone, sizeof(int), IAS_ODL_Int, emeta_odl,
182  "PROJECTION", "UTM_ZONE", &count ) != SUCCESS )
183  {
184  IAS_LOG_ERROR("Reading UTM_ZONE from PROJECTION group.");
185  return(ERROR);
186  }
187  }
188  if ( ias_odl_get_field( projection->projprms, IAS_PROJ_PARAM_SIZE*sizeof(double), IAS_ODL_Double, emeta_odl,
189  "PROJECTION", "PROJECTION_PARAMETERS", &count ) != SUCCESS )
190  {
191  IAS_LOG_ERROR("Reading PROJECTION_PARAMETERS from PROJECTION group.");
192  return(ERROR);
193  }
194  if ( ias_odl_get_field( coords, 2*sizeof(double), IAS_ODL_Double, emeta_odl,
195  "PROJECTION", "UL_CORNER", &count ) != SUCCESS )
196  {
197  IAS_LOG_ERROR("Reading UL_CORNER from PROJECTION group.");
198  return(ERROR);
199  }
200  projection->corners.upleft.x = coords[0];
201  projection->corners.upleft.y = coords[1];
202  if ( ias_odl_get_field( coords, 2*sizeof(double), IAS_ODL_Double, emeta_odl,
203  "PROJECTION", "UR_CORNER", &count ) != SUCCESS )
204  {
205  IAS_LOG_ERROR("Reading UR_CORNER from PROJECTION group.");
206  return(ERROR);
207  }
208  projection->corners.upright.x = coords[0];
209  projection->corners.upright.y = coords[1];
210  if ( ias_odl_get_field( coords, 2*sizeof(double), IAS_ODL_Double, emeta_odl,
211  "PROJECTION", "LL_CORNER", &count ) != SUCCESS )
212  {
213  IAS_LOG_ERROR("Reading LL_CORNER from PROJECTION group.");
214  return(ERROR);
215  }
216  projection->corners.loleft.x = coords[0];
217  projection->corners.loleft.y = coords[1];
218  if ( ias_odl_get_field( coords, 2*sizeof(double), IAS_ODL_Double, emeta_odl,
219  "PROJECTION", "LR_CORNER", &count ) != SUCCESS )
220  {
221  IAS_LOG_ERROR("Reading LR_CORNER from PROJECTION group.");
222  return(ERROR);
223  }
224  projection->corners.loright.x = coords[0];
225  projection->corners.loright.y = coords[1];
226 
227  return(SUCCESS);
228 }
229 
231  EMETA *emeta, /* Enhanced metadata structure to load */
232  IAS_OBJ_DESC *emeta_odl ) /* Enhanced metadata ODL object */
233 {
234  int i; /* Loop index */
235  int year; /* Year of acquisition */
236  int day; /* Day of acquisition */
237  double *dbuffer; /* Local array for loading values */
238  int count; /* Counter for ODL read routines */
239 
240  /* Read data */
241  /* Ephemeris data group */
242  /* Ephemeris epoch time - year */
243  if ( ias_odl_get_field( &year, sizeof(int), IAS_ODL_Int, emeta_odl,
244  "EPHEMERIS", "EPHEMERIS_EPOCH_YEAR", &count ) != SUCCESS )
245  {
246  IAS_LOG_ERROR("Reading EPHEMERIS_EPOCH_YEAR from EPHEMERIS group.");
247  return(ERROR);
248  }
249  emeta->eph_epoch_time[0] = (double)year;
250  /* Ephemeris epoch time - day of year */
251  if ( ias_odl_get_field( &day, sizeof(int), IAS_ODL_Int, emeta_odl,
252  "EPHEMERIS", "EPHEMERIS_EPOCH_DAY", &count ) != SUCCESS )
253  {
254  IAS_LOG_ERROR("Reading EPHEMERIS_EPOCH_DAY from EPHEMERIS group.");
255  return(ERROR);
256  }
257  emeta->eph_epoch_time[1] = (double)day;
258  /* Ephemeris epoch time - second of day */
259  if ( ias_odl_get_field( &emeta->eph_epoch_time[2], sizeof(double), IAS_ODL_Double, emeta_odl,
260  "EPHEMERIS", "EPHEMERIS_EPOCH_SECOND", &count ) != SUCCESS )
261  {
262  if ( ias_odl_get_field( &emeta->eph_epoch_time[2], sizeof(double), IAS_ODL_Double, emeta_odl,
263  "EPHEMERIS", "EPHEMERIS_EPOCH_SECONDS", &count ) != SUCCESS )
264  {
265  IAS_LOG_ERROR("Reading EPHEMERIS_EPOCH_SECONDS from EPHEMERIS group.");
266  return(ERROR);
267  }
268  }
269  /* Number of ephemeris points */
270  if ( ias_odl_get_field( &emeta->ephem_count, sizeof(int), IAS_ODL_Int, emeta_odl,
271  "EPHEMERIS", "NUMBER_OF_POINTS", &count ) != SUCCESS )
272  {
273  IAS_LOG_ERROR("Reading NUMBER_OF_POINTS from EPHEMERIS group.");
274  return(ERROR);
275  }
276  /* Allocate space for the input buffer */
277  dbuffer = (double *)malloc( emeta->ephem_count*sizeof(double) );
278  if ( dbuffer == NULL )
279  {
280  IAS_LOG_ERROR("Allocating ephemeris buffer.");
281  return(ERROR);
282  }
283  /* Allocate space for the ephemeris points */
284  if ( emeta_allocate_ephemeris( emeta, emeta->ephem_count ) != SUCCESS )
285  {
286  IAS_LOG_ERROR("Allocating enhanced metadata ephemeris structure.");
287  free( dbuffer );
288  return(ERROR);
289  }
290  /* Ephemeris sample time offsets from epoch */
291  if ( ias_odl_get_field( dbuffer, emeta->ephem_count*sizeof(double), IAS_ODL_Double, emeta_odl,
292  "EPHEMERIS", "EPHEMERIS_TIME", &count ) != SUCCESS )
293  {
294  IAS_LOG_ERROR("Reading EPHEMERIS_TIME from EPHEMERIS group.");
295  return(ERROR);
296  }
297  for ( i=0; i<emeta->ephem_count; i++ ) emeta->ephemeris[i].eph_sample_time = dbuffer[i];
298  /* Ephemeris ECEF X coordinates */
299  if ( ias_odl_get_field( dbuffer, emeta->ephem_count*sizeof(double), IAS_ODL_Double, emeta_odl,
300  "EPHEMERIS", "EPHEMERIS_ECEF_X", &count ) != SUCCESS )
301  {
302  IAS_LOG_ERROR("Reading EPHEMERIS_ECEF_X from EPHEMERIS group.");
303  return(ERROR);
304  }
305  for ( i=0; i<emeta->ephem_count; i++ ) emeta->ephemeris[i].ecef_position.x = dbuffer[i];
306  /* Ephemeris ECEF Y coordinates */
307  if ( ias_odl_get_field( dbuffer, emeta->ephem_count*sizeof(double), IAS_ODL_Double, emeta_odl,
308  "EPHEMERIS", "EPHEMERIS_ECEF_Y", &count ) != SUCCESS )
309  {
310  IAS_LOG_ERROR("Reading EPHEMERIS_ECEF_Y from EPHEMERIS group.");
311  return(ERROR);
312  }
313  for ( i=0; i<emeta->ephem_count; i++ ) emeta->ephemeris[i].ecef_position.y = dbuffer[i];
314  /* Ephemeris ECEF Z coordinates */
315  if ( ias_odl_get_field( dbuffer, emeta->ephem_count*sizeof(double), IAS_ODL_Double, emeta_odl,
316  "EPHEMERIS", "EPHEMERIS_ECEF_Z", &count ) != SUCCESS )
317  {
318  IAS_LOG_ERROR("Reading EPHEMERIS_ECEF_Z from EPHEMERIS group.");
319  return(ERROR);
320  }
321  for ( i=0; i<emeta->ephem_count; i++ ) emeta->ephemeris[i].ecef_position.z = dbuffer[i];
322  /* Solar vector data group */
323  /* Solar vector sample time offsets from epoch */
324  if ( ias_odl_get_field( dbuffer, emeta->ephem_count*sizeof(double), IAS_ODL_Double, emeta_odl,
325  "SOLAR_VECTOR", "SAMPLE_TIME", &count ) != SUCCESS )
326  {
327  IAS_LOG_ERROR("Reading SAMPLE_TIME from SOLAR_VECTOR group.");
328  return(ERROR);
329  }
330  for ( i=0; i<emeta->ephem_count; i++ ) emeta->sunvector[i].eph_sample_time = dbuffer[i];
331  /* Solar vector ECEF X coordinates */
332  if ( ias_odl_get_field( dbuffer, emeta->ephem_count*sizeof(double), IAS_ODL_Double, emeta_odl,
333  "SOLAR_VECTOR", "SOLAR_ECEF_X", &count ) != SUCCESS )
334  {
335  IAS_LOG_ERROR("Reading SOLAR_ECEF_X from SOLAR_VECTOR group.");
336  return(ERROR);
337  }
338  for ( i=0; i<emeta->ephem_count; i++ ) emeta->sunvector[i].ecef_position.x = dbuffer[i];
339  /* Solar vector ECEF Y coordinates */
340  if ( ias_odl_get_field( dbuffer, emeta->ephem_count*sizeof(double), IAS_ODL_Double, emeta_odl,
341  "SOLAR_VECTOR", "SOLAR_ECEF_Y", &count ) != SUCCESS )
342  {
343  IAS_LOG_ERROR("Reading SOLAR_ECEF_Y from SOLAR_VECTOR group.");
344  return(ERROR);
345  }
346  for ( i=0; i<emeta->ephem_count; i++ ) emeta->sunvector[i].ecef_position.y = dbuffer[i];
347  /* Solar vector ECEF Z coordinates */
348  if ( ias_odl_get_field( dbuffer, emeta->ephem_count*sizeof(double), IAS_ODL_Double, emeta_odl,
349  "SOLAR_VECTOR", "SOLAR_ECEF_Z", &count ) != SUCCESS )
350  {
351  IAS_LOG_ERROR("Reading SOLAR_ECEF_Z from SOLAR_VECTOR group.");
352  return(ERROR);
353  }
354  for ( i=0; i<emeta->ephem_count; i++ ) emeta->sunvector[i].ecef_position.z = dbuffer[i];
355 
356  /* Free the input buffer */
357  free( dbuffer );
358 
359  return(SUCCESS);
360 }
361 
363  EMETA_BAND *band_emeta, /* Enhanced metadata band structure to load */
364  IAS_OBJ_DESC *emeta_odl ) /* Enhanced metadata ODL object */
365 {
366  int i; /* Loop index */
367  int count; /* Counter for ODL read routines */
368  int sca_list[IAS_MAX_NSCAS]; /* Input buffer for SCA list */
369  char band_group[11]; /* Band group name */
370  char field_name[MAX_FIELD_NAME]; /* Field name */
371 
372  /* Read data */
373  /* Band information */
374  /* Construct the current band's group name */
375  sprintf( band_group, "RPC_BAND%02d", band_emeta->band );
376  /* Read the number of SCAs for this band */
377  if ( ias_odl_get_field( &band_emeta->nsca, sizeof(int), IAS_ODL_Int, emeta_odl,
378  band_group, "NUMBER_OF_SCAS", &count ) != SUCCESS )
379  {
380  sprintf(field_name, "BAND%02d_NUMBER_OF_SCAS", band_emeta->band);
381  if ( ias_odl_get_field( &band_emeta->nsca, sizeof(int), IAS_ODL_Int, emeta_odl,
382  band_group, field_name, &count ) != SUCCESS )
383  {
384  IAS_LOG_ERROR("Reading NUMBER_OF_SCAS from %s group.", band_group);
385  return(ERROR);
386  }
387  }
388  /* Read the number of L1T lines for this band */
389  if ( ias_odl_get_field( &band_emeta->l1t_lines, sizeof(int), IAS_ODL_Int, emeta_odl,
390  band_group, "NUM_L1T_LINES", &count ) != SUCCESS )
391  {
392  sprintf(field_name, "BAND%02d_NUM_L1T_LINES", band_emeta->band);
393  if ( ias_odl_get_field( &band_emeta->l1t_lines, sizeof(int), IAS_ODL_Int, emeta_odl,
394  band_group, field_name, &count ) != SUCCESS )
395  {
396  IAS_LOG_ERROR("Reading NUM_L1T_LINES from %s group.", band_group);
397  return(ERROR);
398  }
399  }
400  /* Read the number of L1T samples for this band */
401  if ( ias_odl_get_field( &band_emeta->l1t_samps, sizeof(int), IAS_ODL_Int, emeta_odl,
402  band_group, "NUM_L1T_SAMPS", &count ) != SUCCESS )
403  {
404  sprintf(field_name, "BAND%02d_NUM_L1T_SAMPS", band_emeta->band);
405  if ( ias_odl_get_field( &band_emeta->l1t_samps, sizeof(int), IAS_ODL_Int, emeta_odl,
406  band_group, field_name, &count ) != SUCCESS )
407  {
408  IAS_LOG_ERROR("Reading NUM_L1T_SAMPS from %s group.", band_group);
409  return(ERROR);
410  }
411  }
412  /* Read the number of L1R lines for this band */
413  if ( ias_odl_get_field( &band_emeta->l1r_lines, sizeof(int), IAS_ODL_Int, emeta_odl,
414  band_group, "NUM_L1R_LINES", &count ) != SUCCESS )
415  {
416  sprintf(field_name, "BAND%02d_NUM_L1R_LINES", band_emeta->band);
417  if ( ias_odl_get_field( &band_emeta->l1r_lines, sizeof(int), IAS_ODL_Int, emeta_odl,
418  band_group, field_name, &count ) != SUCCESS )
419  {
420  IAS_LOG_ERROR("Reading NUM_L1R_LINES from %s group.", band_group);
421  return(ERROR);
422  }
423  }
424  /* Read the number of L1R samples for this band */
425  if ( ias_odl_get_field( &band_emeta->l1r_samps, sizeof(int), IAS_ODL_Int, emeta_odl,
426  band_group, "NUM_L1R_SAMPS", &count ) != SUCCESS )
427  {
428  sprintf(field_name, "BAND%02d_NUM_L1R_SAMPS", band_emeta->band);
429  if ( ias_odl_get_field( &band_emeta->l1r_samps, sizeof(int), IAS_ODL_Int, emeta_odl,
430  band_group, field_name, &count ) != SUCCESS )
431  {
432  IAS_LOG_ERROR("Reading NUM_L1R_SAMPS from %s group.", band_group);
433  return(ERROR);
434  }
435  }
436  /* Read the pixel size for this band */
437  if ( ias_odl_get_field( &band_emeta->pixsize, sizeof(double), IAS_ODL_Double, emeta_odl,
438  band_group, "PIXEL_SIZE", &count ) != SUCCESS )
439  {
440  sprintf(field_name, "BAND%02d_PIXEL_SIZE", band_emeta->band);
441  if ( ias_odl_get_field( &band_emeta->pixsize, sizeof(double), IAS_ODL_Double, emeta_odl,
442  band_group, field_name, &count ) != SUCCESS )
443  {
444  IAS_LOG_ERROR("Reading PIXEL_SIZE from %s group.", band_group);
445  return(ERROR);
446  }
447  }
448  /* Read the image start time for this band */
449  if ( ias_odl_get_field( &band_emeta->img_start_time, sizeof(double), IAS_ODL_Double, emeta_odl,
450  band_group, "START_TIME", &count ) != SUCCESS )
451  {
452  sprintf(field_name, "BAND%02d_START_TIME", band_emeta->band);
453  if ( ias_odl_get_field( &band_emeta->img_start_time, sizeof(double), IAS_ODL_Double, emeta_odl,
454  band_group, field_name, &count ) != SUCCESS )
455  {
456  IAS_LOG_ERROR("Reading START_TIME from %s group.", band_group);
457  return(ERROR);
458  }
459  }
460  /* Read the line time for this band */
461  if ( ias_odl_get_field( &band_emeta->line_time, sizeof(double), IAS_ODL_Double, emeta_odl,
462  band_group, "LINE_TIME", &count ) != SUCCESS )
463  {
464  sprintf(field_name, "BAND%02d_LINE_TIME", band_emeta->band);
465  if ( ias_odl_get_field( &band_emeta->line_time, sizeof(double), IAS_ODL_Double, emeta_odl,
466  band_group, field_name, &count ) != SUCCESS )
467  {
468  IAS_LOG_ERROR("Reading LINE_TIME from %s group.", band_group);
469  return(ERROR);
470  }
471  }
472  /* Satellite vector RPC model */
473  sprintf(field_name, "BAND%02d_MEAN_HEIGHT", band_emeta->band );
474  if ( ias_odl_get_field( &band_emeta->sat.mean_hgt, sizeof(double), IAS_ODL_Double, emeta_odl,
475  band_group, field_name, &count ) != SUCCESS )
476  {
477  IAS_LOG_ERROR("Reading %s from %s group.", field_name, band_group);
478  return(ERROR);
479  }
480  sprintf(field_name, "BAND%02d_MEAN_L1R_LINE_SAMP", band_emeta->band );
481  if ( ias_odl_get_field( band_emeta->sat.mean_l1r, 2*sizeof(double), IAS_ODL_Double, emeta_odl,
482  band_group, field_name, &count ) != SUCCESS )
483  {
484  IAS_LOG_ERROR("Reading %s from %s group.", field_name, band_group);
485  return(ERROR);
486  }
487  sprintf(field_name, "BAND%02d_MEAN_L1T_LINE_SAMP", band_emeta->band );
488  if ( ias_odl_get_field( band_emeta->sat.mean_l1t, 2*sizeof(double), IAS_ODL_Double, emeta_odl,
489  band_group, field_name, &count ) != SUCCESS )
490  {
491  IAS_LOG_ERROR("Reading %s from %s group.", field_name, band_group);
492  return(ERROR);
493  }
494  sprintf(field_name, "BAND%02d_MEAN_SAT_VECTOR", band_emeta->band );
495  if ( ias_odl_get_field( band_emeta->sat.mean_vec, 3*sizeof(double), IAS_ODL_Double, emeta_odl,
496  band_group, field_name, &count ) != SUCCESS )
497  {
498  IAS_LOG_ERROR("Reading %s from %s group.", field_name, band_group);
499  return(ERROR);
500  }
501  sprintf(field_name, "BAND%02d_SAT_X_NUM_COEF", band_emeta->band );
502  if ( ias_odl_get_field( band_emeta->sat.x_num, ANG_RPC_COEF*sizeof(double), IAS_ODL_Double, emeta_odl,
503  band_group, field_name, &count ) != SUCCESS )
504  {
505  IAS_LOG_ERROR("Reading %s from %s group.", field_name, band_group);
506  return(ERROR);
507  }
508  sprintf(field_name, "BAND%02d_SAT_X_DEN_COEF", band_emeta->band );
509  if ( ias_odl_get_field( band_emeta->sat.x_den, (ANG_RPC_COEF-1)*sizeof(double), IAS_ODL_Double, emeta_odl,
510  band_group, field_name, &count ) != SUCCESS )
511  {
512  IAS_LOG_ERROR("Reading %s from %s group.", field_name, band_group);
513  return(ERROR);
514  }
515  sprintf(field_name, "BAND%02d_SAT_Y_NUM_COEF", band_emeta->band );
516  if ( ias_odl_get_field( band_emeta->sat.y_num, ANG_RPC_COEF*sizeof(double), IAS_ODL_Double, emeta_odl,
517  band_group, field_name, &count ) != SUCCESS )
518  {
519  IAS_LOG_ERROR("Reading %s from %s group.", field_name, band_group);
520  return(ERROR);
521  }
522  sprintf(field_name, "BAND%02d_SAT_Y_DEN_COEF", band_emeta->band );
523  if ( ias_odl_get_field( band_emeta->sat.y_den, (ANG_RPC_COEF-1)*sizeof(double), IAS_ODL_Double, emeta_odl,
524  band_group, field_name, &count ) != SUCCESS )
525  {
526  IAS_LOG_ERROR("Reading %s from %s group.", field_name, band_group);
527  return(ERROR);
528  }
529  sprintf(field_name, "BAND%02d_SAT_Z_NUM_COEF", band_emeta->band );
530  if ( ias_odl_get_field( band_emeta->sat.z_num, ANG_RPC_COEF*sizeof(double), IAS_ODL_Double, emeta_odl,
531  band_group, field_name, &count ) != SUCCESS )
532  {
533  IAS_LOG_ERROR("Reading %s from %s group.", field_name, band_group);
534  return(ERROR);
535  }
536  sprintf(field_name, "BAND%02d_SAT_Z_DEN_COEF", band_emeta->band );
537  if ( ias_odl_get_field( band_emeta->sat.z_den, (ANG_RPC_COEF-1)*sizeof(double), IAS_ODL_Double, emeta_odl,
538  band_group, field_name, &count ) != SUCCESS )
539  {
540  IAS_LOG_ERROR("Reading %s from %s group.", field_name, band_group);
541  return(ERROR);
542  }
543  /* Solar vector RPC model */
544  band_emeta->sun.mean_hgt = band_emeta->sat.mean_hgt;
545  band_emeta->sun.mean_l1r[0] = band_emeta->sat.mean_l1r[0];
546  band_emeta->sun.mean_l1r[1] = band_emeta->sat.mean_l1r[1];
547  band_emeta->sat.mean_l1t[0] = band_emeta->sat.mean_l1t[0];
548  band_emeta->sat.mean_l1t[1] = band_emeta->sat.mean_l1t[1];
549  sprintf(field_name, "BAND%02d_MEAN_SUN_VECTOR", band_emeta->band );
550  if ( ias_odl_get_field( band_emeta->sun.mean_vec, 3*sizeof(double), IAS_ODL_Double, emeta_odl,
551  band_group, field_name, &count ) != SUCCESS )
552  {
553  IAS_LOG_ERROR("Reading %s from %s group.", field_name, band_group);
554  return(ERROR);
555  }
556  sprintf(field_name, "BAND%02d_SUN_X_NUM_COEF", band_emeta->band );
557  if ( ias_odl_get_field( band_emeta->sun.x_num, ANG_RPC_COEF*sizeof(double), IAS_ODL_Double, emeta_odl,
558  band_group, field_name, &count ) != SUCCESS )
559  {
560  IAS_LOG_ERROR("Reading %s from %s group.", field_name, band_group);
561  return(ERROR);
562  }
563  sprintf(field_name, "BAND%02d_SUN_X_DEN_COEF", band_emeta->band );
564  if ( ias_odl_get_field( band_emeta->sun.x_den, (ANG_RPC_COEF-1)*sizeof(double), IAS_ODL_Double, emeta_odl,
565  band_group, field_name, &count ) != SUCCESS )
566  {
567  IAS_LOG_ERROR("Reading %s from %s group.", field_name, band_group);
568  return(ERROR);
569  }
570  sprintf(field_name, "BAND%02d_SUN_Y_NUM_COEF", band_emeta->band );
571  if ( ias_odl_get_field( band_emeta->sun.y_num, ANG_RPC_COEF*sizeof(double), IAS_ODL_Double, emeta_odl,
572  band_group, field_name, &count ) != SUCCESS )
573  {
574  IAS_LOG_ERROR("Reading %s from %s group.", field_name, band_group);
575  return(ERROR);
576  }
577  sprintf(field_name, "BAND%02d_SUN_Y_DEN_COEF", band_emeta->band );
578  if ( ias_odl_get_field( band_emeta->sun.y_den, (ANG_RPC_COEF-1)*sizeof(double), IAS_ODL_Double, emeta_odl,
579  band_group, field_name, &count ) != SUCCESS )
580  {
581  IAS_LOG_ERROR("Reading %s from %s group.", field_name, band_group);
582  return(ERROR);
583  }
584  sprintf(field_name, "BAND%02d_SUN_Z_NUM_COEF", band_emeta->band );
585  if ( ias_odl_get_field( band_emeta->sun.z_num, ANG_RPC_COEF*sizeof(double), IAS_ODL_Double, emeta_odl,
586  band_group, field_name, &count ) != SUCCESS )
587  {
588  IAS_LOG_ERROR("Reading %s from %s group.", field_name, band_group);
589  return(ERROR);
590  }
591  sprintf(field_name, "BAND%02d_SUN_Z_DEN_COEF", band_emeta->band );
592  if ( ias_odl_get_field( band_emeta->sun.z_den, (ANG_RPC_COEF-1)*sizeof(double), IAS_ODL_Double, emeta_odl,
593  band_group, field_name, &count ) != SUCCESS )
594  {
595  IAS_LOG_ERROR("Reading %s from %s group.", field_name, band_group);
596  return(ERROR);
597  }
598 
599  /* SCA numbers */
600  sprintf(field_name, "BAND%02d_SCA_LIST", band_emeta->band );
601  if ( ias_odl_get_field( sca_list, IAS_MAX_NSCAS*sizeof(int), IAS_ODL_Int, emeta_odl,
602  band_group, field_name, &count ) != SUCCESS ||
603  count != band_emeta->nsca )
604  {
605  IAS_LOG_ERROR("Reading %s from %s group.", field_name, band_group);
606  return(ERROR);
607  }
608 
609  /* Loop through the SCAs */
610  for ( i=0; i<band_emeta->nsca; i++ )
611  {
612  band_emeta->rpc[i].sca_num = sca_list[i];
613  sprintf(field_name, "BAND%02d_SCA%02d_MEAN_HEIGHT", band_emeta->band, band_emeta->rpc[i].sca_num );
614  if ( ias_odl_get_field( &band_emeta->rpc[i].mean_hgt, sizeof(double), IAS_ODL_Double, emeta_odl,
615  band_group, field_name, &count ) != SUCCESS )
616  {
617  IAS_LOG_ERROR("Reading %s from %s group.", field_name, band_group);
618  return(ERROR);
619  }
620  sprintf(field_name, "BAND%02d_SCA%02d_MEAN_L1R_LINE_SAMP", band_emeta->band, band_emeta->rpc[i].sca_num );
621  if ( ias_odl_get_field( band_emeta->rpc[i].mean_l1r, 2*sizeof(double), IAS_ODL_Double, emeta_odl,
622  band_group, field_name, &count ) != SUCCESS )
623  {
624  IAS_LOG_ERROR("Reading %s from %s group.", field_name, band_group);
625  return(ERROR);
626  }
627  sprintf(field_name, "BAND%02d_SCA%02d_MEAN_L1T_LINE_SAMP", band_emeta->band, band_emeta->rpc[i].sca_num );
628  if ( ias_odl_get_field( band_emeta->rpc[i].mean_l1t, 2*sizeof(double), IAS_ODL_Double, emeta_odl,
629  band_group, field_name, &count ) != SUCCESS )
630  {
631  IAS_LOG_ERROR("Reading %s from %s group.", field_name, band_group);
632  return(ERROR);
633  }
634  sprintf(field_name, "BAND%02d_SCA%02d_LINE_NUM_COEF", band_emeta->band, band_emeta->rpc[i].sca_num );
635  if ( ias_odl_get_field( band_emeta->rpc[i].line_num, NUM_RPC_COEF*sizeof(double), IAS_ODL_Double, emeta_odl,
636  band_group, field_name, &count ) != SUCCESS )
637  {
638  IAS_LOG_ERROR("Reading %s from %s group.", field_name, band_group);
639  return(ERROR);
640  }
641  sprintf(field_name, "BAND%02d_SCA%02d_LINE_DEN_COEF", band_emeta->band, band_emeta->rpc[i].sca_num );
642  if ( ias_odl_get_field( band_emeta->rpc[i].line_den, (NUM_RPC_COEF-1)*sizeof(double), IAS_ODL_Double, emeta_odl,
643  band_group, field_name, &count ) != SUCCESS )
644  {
645  IAS_LOG_ERROR("Reading %s from %s group.", field_name, band_group);
646  return(ERROR);
647  }
648  sprintf(field_name, "BAND%02d_SCA%02d_SAMP_NUM_COEF", band_emeta->band, band_emeta->rpc[i].sca_num );
649  if ( ias_odl_get_field( band_emeta->rpc[i].samp_num, NUM_RPC_COEF*sizeof(double), IAS_ODL_Double, emeta_odl,
650  band_group, field_name, &count ) != SUCCESS )
651  {
652  IAS_LOG_ERROR("Reading %s from %s group.", field_name, band_group);
653  return(ERROR);
654  }
655  sprintf(field_name, "BAND%02d_SCA%02d_SAMP_DEN_COEF", band_emeta->band, band_emeta->rpc[i].sca_num );
656  if ( ias_odl_get_field( band_emeta->rpc[i].samp_den, (NUM_RPC_COEF-1)*sizeof(double), IAS_ODL_Double, emeta_odl,
657  band_group, field_name, &count ) != SUCCESS )
658  {
659  IAS_LOG_ERROR("Reading %s from %s group.", field_name, band_group);
660  return(ERROR);
661  }
662  }
663 
664  return(SUCCESS);
665 }
666 
667 int emeta_angles_rpc(
668  double l1t_line, /* Output space line coordinate */
669  double l1t_samp, /* Output space sample coordinate */
670  EMETA *emeta, /* Enhanced metadata structure */
671  int band, /* Current band number */
672  double *satang, /* Satellite viewing zenith/azimuth angles */
673  double *sunang ) /* Solar illumination zenith/azimuth angles */
674 {
675  int band_index; /* Band index in EMETA structure */
676  int nsca_found; /* Number of SCAS containing the point */
677  int isca; /* SCA index */
678  double height; /* Model height */
679  double l1r_line[2]; /* Input space (L1R) line coordinate */
680  double l1r_samp[2]; /* Input space (L1R) sample coordinate */
681  double sat_zen; /* Satellite zenith angle */
682  double sat_az; /* Satellite azimuth angle */
683  double sun_zen; /* Solar zenith angle */
684  double sun_az; /* Solar azimuth angle */
685  double hdist; /* Horizontal component of vector */
686  IAS_VECTOR satvec; /* Satellite viewing vector */
687  IAS_VECTOR sunvec; /* Solar illumination vector */
688 
689  /* Set the band index */
690  if ( (band_index = emeta_band_number_to_index( emeta, band )) < 0 )
691  {
692  IAS_LOG_ERROR("Band number %d not valid.", band);
693  return(ERROR);
694  }
695 
696  /* Set the height to use */
697  height = emeta->band_emeta[band_index].sat.mean_hgt;
698 
699  /* Initialize the output vectors */
700  satang[0] = satang[1] = 0.0;
701  sunang[0] = sunang[1] = 0.0;
702 
703  /* See which SCA(s) the point falls inside */
704  nsca_found = emeta_find_scas( l1t_line, l1t_samp, &(emeta->band_emeta[band_index]),
705  l1r_line, l1r_samp );
706 
707  if ( nsca_found < 1 ) return(SUCCESS); /* Outside active image, return zero vectors */
708  if ( nsca_found > 2 )
709  {
710  IAS_LOG_ERROR("Too many SCAs found locating point in active image.");
711  return(ERROR);
712  }
713 
714  /* Offset the output space coordinates */
715  l1t_line -= emeta->band_emeta[band_index].sat.mean_l1t[0];
716  l1t_samp -= emeta->band_emeta[band_index].sat.mean_l1t[1];
717  height -= emeta->band_emeta[band_index].sat.mean_hgt;
718 
719  /* Check the located SCAs */
720  for ( isca=0; isca<nsca_found; isca++ )
721  {
722  /* Calculate the vectors using the RPCs */
723  /* Satellite vector */
724  l1r_line[isca] -= emeta->band_emeta[band_index].sat.mean_l1r[0];
725  l1r_samp[isca] -= emeta->band_emeta[band_index].sat.mean_l1r[1];
726 
727  satvec.x = emeta->band_emeta[band_index].sat.mean_vec[0]
728  + (emeta->band_emeta[band_index].sat.x_num[0]
729  + l1t_line*(emeta->band_emeta[band_index].sat.x_num[1]
730  + emeta->band_emeta[band_index].sat.x_num[5]*l1t_line
731  + emeta->band_emeta[band_index].sat.x_num[6]*l1t_samp)
732  + l1t_samp*(emeta->band_emeta[band_index].sat.x_num[2]
733  + emeta->band_emeta[band_index].sat.x_num[7]*l1t_samp)
734  + emeta->band_emeta[band_index].sat.x_num[3]*height
735  + l1r_line[isca]*(emeta->band_emeta[band_index].sat.x_num[4]
736  + l1r_line[isca]*(emeta->band_emeta[band_index].sat.x_num[8]*l1r_samp[isca]
737  + emeta->band_emeta[band_index].sat.x_num[9]*l1r_line[isca])))
738  / (1.0
739  + l1t_line*(emeta->band_emeta[band_index].sat.x_den[0]
740  + emeta->band_emeta[band_index].sat.x_den[4]*l1t_line
741  + emeta->band_emeta[band_index].sat.x_den[5]*l1t_samp)
742  + l1t_samp*(emeta->band_emeta[band_index].sat.x_den[1]
743  + emeta->band_emeta[band_index].sat.x_den[6]*l1t_samp)
744  + emeta->band_emeta[band_index].sat.x_den[2]*height
745  + l1r_line[isca]*(emeta->band_emeta[band_index].sat.x_den[3]
746  + l1r_line[isca]*(emeta->band_emeta[band_index].sat.x_den[7]*l1r_samp[isca]
747  + emeta->band_emeta[band_index].sat.x_den[8]*l1r_line[isca])));
748 
749  satvec.y = emeta->band_emeta[band_index].sat.mean_vec[1]
750  + (emeta->band_emeta[band_index].sat.y_num[0]
751  + l1t_line*(emeta->band_emeta[band_index].sat.y_num[1]
752  + emeta->band_emeta[band_index].sat.y_num[5]*l1t_line
753  + emeta->band_emeta[band_index].sat.y_num[6]*l1t_samp)
754  + l1t_samp*(emeta->band_emeta[band_index].sat.y_num[2]
755  + emeta->band_emeta[band_index].sat.y_num[7]*l1t_samp)
756  + emeta->band_emeta[band_index].sat.y_num[3]*height
757  + l1r_line[isca]*(emeta->band_emeta[band_index].sat.y_num[4]
758  + l1r_line[isca]*(emeta->band_emeta[band_index].sat.y_num[8]*l1r_samp[isca]
759  + emeta->band_emeta[band_index].sat.y_num[9]*l1r_line[isca])))
760  / (1.0
761  + l1t_line*(emeta->band_emeta[band_index].sat.y_den[0]
762  + emeta->band_emeta[band_index].sat.y_den[4]*l1t_line
763  + emeta->band_emeta[band_index].sat.y_den[5]*l1t_samp)
764  + l1t_samp*(emeta->band_emeta[band_index].sat.y_den[1]
765  + emeta->band_emeta[band_index].sat.y_den[6]*l1t_samp)
766  + emeta->band_emeta[band_index].sat.y_den[2]*height
767  + l1r_line[isca]*(emeta->band_emeta[band_index].sat.y_den[3]
768  + l1r_line[isca]*(emeta->band_emeta[band_index].sat.y_den[7]*l1r_samp[isca]
769  + emeta->band_emeta[band_index].sat.y_den[8]*l1r_line[isca])));
770 
771  satvec.z = emeta->band_emeta[band_index].sat.mean_vec[2]
772  + (emeta->band_emeta[band_index].sat.z_num[0]
773  + l1t_line*(emeta->band_emeta[band_index].sat.z_num[1]
774  + emeta->band_emeta[band_index].sat.z_num[5]*l1t_line
775  + emeta->band_emeta[band_index].sat.z_num[6]*l1t_samp)
776  + l1t_samp*(emeta->band_emeta[band_index].sat.z_num[2]
777  + emeta->band_emeta[band_index].sat.z_num[7]*l1t_samp)
778  + emeta->band_emeta[band_index].sat.z_num[3]*height
779  + l1r_line[isca]*(emeta->band_emeta[band_index].sat.z_num[4]
780  + l1r_line[isca]*(emeta->band_emeta[band_index].sat.z_num[8]*l1r_samp[isca]
781  + emeta->band_emeta[band_index].sat.z_num[9]*l1r_line[isca])))
782  / (1.0
783  + l1t_line*(emeta->band_emeta[band_index].sat.z_den[0]
784  + emeta->band_emeta[band_index].sat.z_den[4]*l1t_line
785  + emeta->band_emeta[band_index].sat.z_den[5]*l1t_samp)
786  + l1t_samp*(emeta->band_emeta[band_index].sat.z_den[1]
787  + emeta->band_emeta[band_index].sat.z_den[6]*l1t_samp)
788  + emeta->band_emeta[band_index].sat.z_den[2]*height
789  + l1r_line[isca]*(emeta->band_emeta[band_index].sat.z_den[3]
790  + l1r_line[isca]*(emeta->band_emeta[band_index].sat.z_den[7]*l1r_samp[isca]
791  + emeta->band_emeta[band_index].sat.z_den[8]*l1r_line[isca])));
792 
793  /* Solar vector */
794  sunvec.x = emeta->band_emeta[band_index].sun.mean_vec[0]
795  + (emeta->band_emeta[band_index].sun.x_num[0]
796  + l1t_line*(emeta->band_emeta[band_index].sun.x_num[1]
797  + emeta->band_emeta[band_index].sun.x_num[5]*l1t_line
798  + emeta->band_emeta[band_index].sun.x_num[6]*l1t_samp)
799  + l1t_samp*(emeta->band_emeta[band_index].sun.x_num[2]
800  + emeta->band_emeta[band_index].sun.x_num[7]*l1t_samp)
801  + emeta->band_emeta[band_index].sun.x_num[3]*height
802  + l1r_line[isca]*(emeta->band_emeta[band_index].sun.x_num[4]
803  + l1r_line[isca]*(emeta->band_emeta[band_index].sun.x_num[8]*l1r_samp[isca]
804  + emeta->band_emeta[band_index].sun.x_num[9]*l1r_line[isca])))
805  / (1.0
806  + l1t_line*(emeta->band_emeta[band_index].sun.x_den[0]
807  + emeta->band_emeta[band_index].sun.x_den[4]*l1t_line
808  + emeta->band_emeta[band_index].sun.x_den[5]*l1t_samp)
809  + l1t_samp*(emeta->band_emeta[band_index].sun.x_den[1]
810  + emeta->band_emeta[band_index].sun.x_den[6]*l1t_samp)
811  + emeta->band_emeta[band_index].sun.x_den[2]*height
812  + l1r_line[isca]*(emeta->band_emeta[band_index].sun.x_den[3]
813  + l1r_line[isca]*(emeta->band_emeta[band_index].sun.x_den[7]*l1r_samp[isca]
814  + emeta->band_emeta[band_index].sun.x_den[8]*l1r_line[isca])));
815 
816  sunvec.y = emeta->band_emeta[band_index].sun.mean_vec[1]
817  + (emeta->band_emeta[band_index].sun.y_num[0]
818  + l1t_line*(emeta->band_emeta[band_index].sun.y_num[1]
819  + emeta->band_emeta[band_index].sun.y_num[5]*l1t_line
820  + emeta->band_emeta[band_index].sun.y_num[6]*l1t_samp)
821  + l1t_samp*(emeta->band_emeta[band_index].sun.y_num[2]
822  + emeta->band_emeta[band_index].sun.y_num[7]*l1t_samp)
823  + emeta->band_emeta[band_index].sun.y_num[3]*height
824  + l1r_line[isca]*(emeta->band_emeta[band_index].sun.y_num[4]
825  + l1r_line[isca]*(emeta->band_emeta[band_index].sun.y_num[8]*l1r_samp[isca]
826  + emeta->band_emeta[band_index].sun.y_num[9]*l1r_line[isca])))
827  / (1.0
828  + l1t_line*(emeta->band_emeta[band_index].sun.y_den[0]
829  + emeta->band_emeta[band_index].sun.y_den[4]*l1t_line
830  + emeta->band_emeta[band_index].sun.y_den[5]*l1t_samp)
831  + l1t_samp*(emeta->band_emeta[band_index].sun.y_den[1]
832  + emeta->band_emeta[band_index].sun.y_den[6]*l1t_samp)
833  + emeta->band_emeta[band_index].sun.y_den[2]*height
834  + l1r_line[isca]*(emeta->band_emeta[band_index].sun.y_den[3]
835  + l1r_line[isca]*(emeta->band_emeta[band_index].sun.y_den[7]*l1r_samp[isca]
836  + emeta->band_emeta[band_index].sun.y_den[8]*l1r_line[isca])));
837 
838  sunvec.z = emeta->band_emeta[band_index].sun.mean_vec[2]
839  + (emeta->band_emeta[band_index].sun.z_num[0]
840  + l1t_line*(emeta->band_emeta[band_index].sun.z_num[1]
841  + emeta->band_emeta[band_index].sun.z_num[5]*l1t_line
842  + emeta->band_emeta[band_index].sun.z_num[6]*l1t_samp)
843  + l1t_samp*(emeta->band_emeta[band_index].sun.z_num[2]
844  + emeta->band_emeta[band_index].sun.z_num[7]*l1t_samp)
845  + emeta->band_emeta[band_index].sun.z_num[3]*height
846  + l1r_line[isca]*(emeta->band_emeta[band_index].sun.z_num[4]
847  + l1r_line[isca]*(emeta->band_emeta[band_index].sun.z_num[8]*l1r_samp[isca]
848  + emeta->band_emeta[band_index].sun.z_num[9]*l1r_line[isca])))
849  / (1.0
850  + l1t_line*(emeta->band_emeta[band_index].sun.z_den[0]
851  + emeta->band_emeta[band_index].sun.z_den[4]*l1t_line
852  + emeta->band_emeta[band_index].sun.z_den[5]*l1t_samp)
853  + l1t_samp*(emeta->band_emeta[band_index].sun.z_den[1]
854  + emeta->band_emeta[band_index].sun.z_den[6]*l1t_samp)
855  + emeta->band_emeta[band_index].sun.z_den[2]*height
856  + l1r_line[isca]*(emeta->band_emeta[band_index].sun.z_den[3]
857  + l1r_line[isca]*(emeta->band_emeta[band_index].sun.z_den[7]*l1r_samp[isca]
858  + emeta->band_emeta[band_index].sun.z_den[8]*l1r_line[isca])));
859 
860  /* Calculate satellite angles from vector */
861  if ( satvec.z > 0.0 ) sat_zen = acos( satvec.z );
862  else sat_zen = 0.0;
863  satang[0] += sat_zen;
864  hdist = satvec.x*satvec.x+satvec.y*satvec.y;
865  if ( hdist > 0.0 ) sat_az = atan2( satvec.x, satvec.y );
866  else sat_az = 0.0;
867  satang[1] += sat_az;
868 
869  /* Calculate solar angles from vector */
870  if ( sunvec.z > 0.0 ) sun_zen = acos( sunvec.z );
871  else sun_zen = 0.0;
872  sunang[0] += sun_zen;
873  hdist = sunvec.x*sunvec.x+sunvec.y*sunvec.y;
874  if ( hdist > 0.0 ) sun_az = atan2( sunvec.x, sunvec.y );
875  else sun_az = 0.0;
876  sunang[1] += sun_az;
877  }
878 
879  /* Average the satellite angles */
880  satang[0] /= (double)nsca_found;
881  satang[1] /= (double)nsca_found;
882 
883  /* Average the sun angles */
884  sunang[0] /= (double)nsca_found;
885  sunang[1] /= (double)nsca_found;
886 
887  return(SUCCESS);
888 }
889 
890 int emeta_find_scas(
891  double l1t_line, /* Input L1T line */
892  double l1t_samp, /* Input L1T sample */
893  EMETA_BAND *eband, /* Enhanced metadata for current band */
894  double *l1r_line, /* Array of output L1R line numbers */
895  double *l1r_samp ) /* Array of output L1R sample numbers */
896 {
897  int isca; /* SCA index */
898  int nsca_found; /* Number of SCAs containing input point */
899  int ntry; /* Number of SCAs tested */
900  static int last_sca = -1; /* Last SCA successfully used */
901  double l1t_l; /* Offset value of L1T line */
902  double l1t_s; /* Offset value of L1T sample */
903  double l1r_l; /* Local L1R line */
904  double l1r_s; /* Local L1R sample */
905 
906  /* Initialize the number found */
907  nsca_found = 0;
908  ntry = 0;
909 
910  /* Try a point in the middle of the band */
911  if ( last_sca < 0 || last_sca >= eband->nsca ) isca = eband->nsca / 2;
912  else isca = last_sca;
913 
914  /* Compute the RPCs for this SCA */
915  while ( isca >= 0 && isca < eband->nsca )
916  {
917  l1t_l = l1t_line - eband->rpc[isca].mean_l1t[0];
918  l1t_s = l1t_samp - eband->rpc[isca].mean_l1t[1];
919 
920  l1r_l = (eband->rpc[isca].line_num[0] + eband->rpc[isca].line_num[1]*l1t_l + (eband->rpc[isca].line_num[2]
921  + eband->rpc[isca].line_num[4]*l1t_l)*l1t_s)
922  / (1.0 + eband->rpc[isca].line_den[0]*l1t_l + (eband->rpc[isca].line_den[1]
923  + eband->rpc[isca].line_den[3]*l1t_l)*l1t_s) + eband->rpc[isca].mean_l1r[0];
924  l1r_s = (eband->rpc[isca].samp_num[0] + eband->rpc[isca].samp_num[1]*l1t_l + (eband->rpc[isca].samp_num[2]
925  + eband->rpc[isca].samp_num[4]*l1t_l)*l1t_s)
926  / (1.0 + eband->rpc[isca].samp_den[0]*l1t_l + (eband->rpc[isca].samp_den[1]
927  + eband->rpc[isca].samp_den[3]*l1t_l)*l1t_s) + eband->rpc[isca].mean_l1r[1];
928 
929  /* See if we are in the right place */
930  if ( l1r_s >= 0 && l1r_s < eband->l1r_samps )
931  {
932  ntry++;
933  if ( l1r_l >= 0 && l1r_l < eband->l1r_lines )
934  {
935  l1r_line[nsca_found] = l1r_l;
936  l1r_samp[nsca_found] = l1r_s + isca * eband->l1r_samps;
937  nsca_found++;
938  }
939  last_sca = isca;
940  if ( ntry > 1 ) return(nsca_found);
941  if ( l1r_s < SCA_OVERLAP ) isca--;
942  else if ( l1r_s > (eband->l1r_samps - SCA_OVERLAP) ) isca++;
943  else return(nsca_found);
944  }
945  else
946  {
947  if ( ntry > 0 ) return(nsca_found);
948  if ( isca == 0 && l1r_s < 0 )
949  {
950  last_sca = isca;
951  return(nsca_found);
952  }
953  if ( isca == (eband->nsca-1) && l1r_s > eband->l1r_samps )
954  {
955  last_sca = isca;
956  return(nsca_found);
957  }
958  isca = (l1r_s + isca * eband->l1r_samps) / eband->l1r_samps;
959  if ( isca < 0 ) isca = 0;
960  if ( isca >= eband->nsca ) isca = eband->nsca - 1;
961  }
962  }
963 
964  return(nsca_found);
965 }
966 
968  char *root_filename, /* Output root file name */
969  short *sat_zn, /* Array of satellite zenith angles */
970  short *sat_az, /* Array of satellite azimuth angles */
971  short *sun_zn, /* Array of solar zenith angles */
972  short *sun_az, /* Array of solar azimuth angles */
973  EMETA_FRAME *frame ) /* Output image framing information */
974 {
975  FILE *ofp; /* Output file pointer */
976  char ang_filename[PATH_MAX]; /* Output angle file name */
977  int count; /* Total number of samples */
978 
979  /* Construct satellite view angle output file name */
980  sprintf( ang_filename, "%s_V%02d.img", root_filename, frame->band );
981  printf("Writing view angle band file %s.\n", ang_filename);
982 
983  /* Open output file */
984  if ( (ofp = fopen( ang_filename, "wb" )) == NULL )
985  {
986  IAS_LOG_ERROR("Opening output view angle band file %s.", ang_filename);
987  return(ERROR);
988  }
989 
990  /* Calculate the total number of samples */
991  count = frame->nlines * frame->nsamps;
992 
993  /* Write the Satellite Zenith Angle layer */
994  if ( fwrite( sat_zn, sizeof(short), count, ofp ) != count )
995  {
996  IAS_LOG_ERROR("Writing satellite zenith angle layer for band %d.", frame->band);
997  fclose(ofp);
998  return(ERROR);
999  }
1000 
1001  /* Write the Satellite Azimuth Angle layer */
1002  if ( fwrite( sat_az, sizeof(short), count, ofp ) != count )
1003  {
1004  IAS_LOG_ERROR("Writing satellite azimuth angle layer for band %d.", frame->band);
1005  fclose(ofp);
1006  return(ERROR);
1007  }
1008 
1009  /* Close the output image file */
1010  fclose(ofp);
1011 
1012  /* Create the output header file name */
1013  strcat( ang_filename, ".hdr" );
1014  printf("Writing view angle band header file %s.\n", ang_filename);
1015 
1016  /* Open the output header file */
1017  if ( (ofp = fopen( ang_filename, "w" )) == NULL )
1018  {
1019  IAS_LOG_ERROR("Opening output ENVI header file %s.", ang_filename);
1020  return(ERROR);
1021  }
1022 
1023  /* Write the output header file */
1024  fprintf( ofp, "ENVI\n" );
1025  fprintf( ofp, "description = {\n" );
1026  fprintf( ofp, " L8 View Angle Band File for %s.}\n", root_filename );
1027  fprintf( ofp, "samples = %d\n", frame->nsamps );
1028  fprintf( ofp, "lines = %d\n", frame->nlines );
1029  fprintf( ofp, "bands = 2\n" );
1030  fprintf( ofp, "header offset = 0\n" );
1031  fprintf( ofp, "file type = ENVI Standard\n" );
1032  fprintf( ofp, "data type = 2\n" );
1033  fprintf( ofp, "interleave = bsq\n" );
1034  fprintf( ofp, "sensor type = Unknown\n" );
1035  fprintf( ofp, "byte order = 0\n" );
1036  if ( frame->code == 1 )
1037  {
1038  fprintf( ofp, "map info = {UTM, 1.500, 1.500, %6.3lf, %6.3lf, %6.3lf, %6.3lf, %d, North, WGS-84, units=Meters}\n",
1039  frame->ul_x, frame->ul_y, frame->pixsize, frame->pixsize, frame->zone );
1040  }
1041  else if ( frame->code == 6 )
1042  {
1043  fprintf( ofp, "map info = {Polar Stereographic, 1.500, 1.500, %6.3lf, %6.3lf, %6.3lf, %6.3lf, WGS-84, units=Meters}\n",
1044  frame->ul_x, frame->ul_y, frame->pixsize, frame->pixsize );
1045  fprintf( ofp, "projection info = {31, 6378137.000, 6356752.314, -71.000000, 0.000000, 0.0, 0.0, WGS-84, Polar Stereographic, units=Meters}\n" );
1046  }
1047  else
1048  {
1049  IAS_LOG_ERROR("Invalid map projection, not UTM or LIMA PS");
1050  return(ERROR);
1051  }
1052  fprintf( ofp, "wavelength units = Unknown\n" );
1053 
1054  /* Close the output header file */
1055  fclose(ofp);
1056 
1057  /* Construct solar angle output file name */
1058  sprintf( ang_filename, "%s_S%02d.img", root_filename, frame->band );
1059  printf("Writing sun angle band file %s.\n", ang_filename);
1060 
1061  /* Open output file */
1062  if ( (ofp = fopen( ang_filename, "wb" )) == NULL )
1063  {
1064  IAS_LOG_ERROR("Opening output sun angle band file %s.", ang_filename);
1065  return(ERROR);
1066  }
1067 
1068  /* Write the Solar Zenith Angle layer */
1069  if ( fwrite( sun_zn, sizeof(short), count, ofp ) != count )
1070  {
1071  IAS_LOG_ERROR("Writing solar zenith angle layer for band %d.", frame->band);
1072  fclose(ofp);
1073  return(ERROR);
1074  }
1075 
1076  /* Write the Solar Azimuth Angle layer */
1077  if ( fwrite( sun_az, sizeof(short), count, ofp ) != count )
1078  {
1079  IAS_LOG_ERROR("Writing solar azimuth angle layer for band %d.", frame->band);
1080  fclose(ofp);
1081  return(ERROR);
1082  }
1083 
1084  /* Close the output image file */
1085  fclose(ofp);
1086 
1087  /* Create the output header file name */
1088  strcat( ang_filename, ".hdr" );
1089  printf("Writing sun angle band header file %s.\n", ang_filename);
1090 
1091  /* Open the output header file */
1092  if ( (ofp = fopen( ang_filename, "w" )) == NULL )
1093  {
1094  IAS_LOG_ERROR("Opening output ENVI header file %s.", ang_filename);
1095  return(ERROR);
1096  }
1097 
1098  /* Write the output header file */
1099  fprintf( ofp, "ENVI\n" );
1100  fprintf( ofp, "description = {\n" );
1101  fprintf( ofp, " L8 Sun Angle Band File for %s.}\n", root_filename );
1102  fprintf( ofp, "samples = %d\n", frame->nsamps );
1103  fprintf( ofp, "lines = %d\n", frame->nlines );
1104  fprintf( ofp, "bands = 2\n" );
1105  fprintf( ofp, "header offset = 0\n" );
1106  fprintf( ofp, "file type = ENVI Standard\n" );
1107  fprintf( ofp, "data type = 2\n" );
1108  fprintf( ofp, "interleave = bsq\n" );
1109  fprintf( ofp, "sensor type = Unknown\n" );
1110  fprintf( ofp, "byte order = 0\n" );
1111  if ( frame->code == 1 )
1112  {
1113  fprintf( ofp, "map info = {UTM, 1.500, 1.500, %6.3lf, %6.3lf, %6.3lf, %6.3lf, %d, North, WGS-84, units=Meters}\n",
1114  frame->ul_x, frame->ul_y, frame->pixsize, frame->pixsize, frame->zone );
1115  }
1116  else if ( frame->code == 6 )
1117  {
1118  fprintf( ofp, "map info = {Polar Stereographic, 1.500, 1.500, %6.3lf, %6.3lf, %6.3lf, %6.3lf, WGS-84, units=Meters}\n",
1119  frame->ul_x, frame->ul_y, frame->pixsize, frame->pixsize );
1120  fprintf( ofp, "projection info = {31, 6378137.000, 6356752.314, -71.000000, 0.000000, 0.0, 0.0, WGS-84, Polar Stereographic, units=Meters}\n" );
1121  }
1122  else
1123  {
1124  IAS_LOG_ERROR("Invalid map projection, not UTM or LIMA PS");
1125  return(ERROR);
1126  }
1127  fprintf( ofp, "wavelength units = Unknown\n" );
1128 
1129  /* Close the output header file */
1130  fclose(ofp);
1131 
1132  return(SUCCESS);
1133 }
1134 
void ias_odl_free_tree(IAS_OBJ_DESC *p_lp)
int emeta_read_file_header(EMETA *emeta, IAS_OBJ_DESC *emeta_odl)
Definition: emeta_exploit.c:78
#define SUCCESS
Definition: ObpgReadGrid.h:15
#define IAS_LOG_ERROR(format,...)
Definition: ias_logging.h:96
EMETA_ANG_RPC sat
Definition: emeta.h:91
int32_t day
double wgs84_major_axis
Definition: emeta.h:59
double eph_sample_time
Definition: emeta.h:98
int emeta_allocate_ephemeris(EMETA *emeta, int nephem)
Definition: emeta.c:12
IAS_DBL_XY upright
subroutine sunvec(procrng, sunproc, navctl, sun_bod)
Definition: sunvec.f:2
double mean_vec[3]
Definition: emeta.h:47
int emeta_read_band_meta(EMETA_BAND *band_emeta, IAS_OBJ_DESC *emeta_odl)
#define NULL
Definition: decode_rs.h:63
#define IAS_MAX_NBANDS
Definition: emeta.h:17
PARAM_TYPE_NONE Default value No parameter is buried in the product name name_prefix is case insensitive string compared to the product name PARAM_TYPE_VIS_WAVE The visible wavelength bands from the sensor are buried in the product name The product name is compared by appending and name_suffix ie aph_412_giop where prod_ix will be set to PARAM_TYPE_IR_WAVE same search method as PARAM_TYPE_VIS_WAVE except only wavelength above are looped through but prod_ix is still based ie aph_2_giop for the second band
int num_band
Definition: emeta.h:107
#define IAS_MAX_NSCAS
Definition: emeta.h:22
int emeta_read(EMETA *emeta, const char *emeta_filename)
Definition: emeta_exploit.c:21
char units[IAS_UNITS_SIZE]
Definition: emeta.h:62
int emeta_read_ephemeris(EMETA *emeta, IAS_OBJ_DESC *emeta_odl)
double projprms[IAS_PROJ_PARAM_SIZE]
Definition: emeta.h:70
int l1t_samps
Definition: emeta.h:84
double x_den[ANG_RPC_COEF-1]
Definition: emeta.h:49
double mean_l1t[2]
Definition: emeta.h:34
double samp_num[NUM_RPC_COEF]
Definition: emeta.h:38
subroutine satang(pi, rad, tilt, roll, pitch, yaw, xlon, ylat, senz, sena)
Definition: satang.f:3
double samp_den[NUM_RPC_COEF-1]
Definition: emeta.h:39
character(len=1000) if
Definition: names.f90:13
IAS_DBL_XY loleft
double mean_l1r[2]
Definition: emeta.h:46
int l1r_samps
Definition: emeta.h:86
int emeta_band_number_to_index(EMETA *emeta, int band)
double pixsize
Definition: emeta_exploit.h:27
#define PATH_MAX
Definition: config.h:129
int l1t_lines
Definition: emeta.h:83
double mean_l1r[2]
Definition: emeta.h:33
IAS_OBJ_DESC * ias_odl_read_tree(const char *p_ODLFile)
double x_num[ANG_RPC_COEF]
Definition: emeta.h:48
double mean_hgt
Definition: emeta.h:45
int ephem_count
Definition: emeta.h:113
double wgs84_minor_axis
Definition: emeta.h:60
IAS_DBL_XY loright
IAS_VECTOR ecef_position
Definition: emeta.h:99
#define NUM_RPC_COEF
Definition: emeta.h:27
EMETA_BAND band_emeta[IAS_MAX_NBANDS]
Definition: emeta.h:108
#define ANG_RPC_COEF
Definition: emeta.h:28
Definition: emeta.h:102
char datum[IAS_DATUM_SIZE]
Definition: emeta.h:66
double mean_l1t[2]
Definition: emeta.h:44
EMETA_EPHEM * sunvector
Definition: emeta.h:115
double line_time
Definition: emeta.h:90
double line_num[NUM_RPC_COEF]
Definition: emeta.h:36
int emeta_find_scas(double l1t_line, double l1t_samp, EMETA_BAND *eband, double *l1r_line, double *l1r_samp)
integer, parameter double
int emeta_angles_rpc(double l1t_line, double l1t_samp, EMETA *emeta, int band, double *satang, double *sunang)
@ IAS_ODL_Double
Definition: ias_odl.h:29
#define MAX_FIELD_NAME
Definition: emeta_exploit.c:19
double eph_epoch_time[3]
Definition: emeta.h:109
int emeta_read_projection(EMETA_SCENE_PROJ *projection, IAS_OBJ_DESC *emeta_odl)
double line_den[NUM_RPC_COEF-1]
Definition: emeta.h:37
EMETA_SCENE_PROJ projection
Definition: emeta.h:106
double mean_hgt
Definition: emeta.h:35
#define SCA_OVERLAP
Definition: emeta_exploit.h:16
IAS_DBL_XY upleft
double img_start_time
Definition: emeta.h:88
int emeta_write_angfile(char *root_filename, short *sat_zn, short *sat_az, short *sun_zn, short *sun_az, EMETA_FRAME *frame)
EMETA_IMG_RPC rpc[IAS_MAX_NSCAS]
Definition: emeta.h:93
double z_den[ANG_RPC_COEF-1]
Definition: emeta.h:53
double y_den[ANG_RPC_COEF-1]
Definition: emeta.h:51
double y_num[ANG_RPC_COEF]
Definition: emeta.h:50
struct IAS_CORNERS corners
Definition: emeta.h:75
double pixsize
Definition: emeta.h:87
int i
Definition: decode_rs.h:71
@ IAS_ODL_Int
Definition: ias_odl.h:32
int sca_num
Definition: emeta.h:32
int ias_odl_get_field(void *p_MemoryAddr, int MemorySize, IAS_ODL_TYPE ValueType, IAS_OBJ_DESC *p_ODLTree, const char *p_ClassName, const char *p_LabelName, int *p_Count)
EMETA_EPHEM * ephemeris
Definition: emeta.h:114
int nsca
Definition: emeta.h:82
#define IAS_PROJ_PARAM_SIZE
Definition: ias_const.h:61
EMETA_ANG_RPC sun
Definition: emeta.h:92
int l1r_lines
Definition: emeta.h:85
#define ERROR
Definition: ancil.h:24
int band
Definition: emeta.h:81
@ IAS_ODL_String
Definition: ias_odl.h:31
double z_num[ANG_RPC_COEF]
Definition: emeta.h:52
int count
Definition: decode_rs.h:79