OB.DAAC Logo
NASA Logo
Ocean Color Science Software

ocssw V2022
GEO_write_scan_data.c
Go to the documentation of this file.
1 #include "PGS_MODIS_35251.h"
2 #include "GEO_global_arrays.h"
3 #include "GEO_product.h"
4 #include "GEO_output.h"
5 #include "GEO_geo.h"
6 
7 PGSt_SMF_status GEO_write_scan_data(
8  MODFILE * const geo_file,
9  int const scan_number,
10  swath_elem_struct const * swath_elem,
11  GEO_param_struct const * GEO_param,
12  double terrain_frame_position[][MAX_FRAMES][3],
13  double frame_to_sensor[][MAX_FRAMES][3],
14  double frame_solar_angles[][MAX_FRAMES][2],
15  uint8 frame_flags[][MAX_FRAMES],
16  uint8 frame_landsea[][MAX_FRAMES],
17  uint8 frame_waterpresent[][MAX_FRAMES],
18  int8 hires_offsets[][DETECTORS_QKM][SAMPLES_QKM]
19  )
20 /*
21 !C******************************************************************************
22 !Description:
23  subroutine in output group of the Level-1A geolocation
24  software to write one scan of spatial element geolocation
25  data to the geolocation product file.
26 
27 !Input Parameters:
28  geo_file MAPI structure for geolocation product to be written to
29  scan_number The scan number to be written.
30  swath_elem The swath values to be written.
31  GEO_param Contains the angle and range scale values.
32  terrain_frame_position Geodetic coordinates of ground position
33  frame_to_sensor Polar coordinates of spacecraft from ground.
34  frame_solar_angles Solar azimuth and zenith angles from ground.
35  frame_flags Pixel level flags
36  hires_offsets High resolution offsets from bilinear
37  interpolation of low resolution positions.
38  frame_landsea Land/Water mask.
39  frame_waterpresent Count of high-resolution pixels with water.
40 
41 
42 !Output Parameters: None
43 
44 Return Values:
45  MODIS_E_BAD_INPUT_ARG If any argument is invalid.
46  MODIS_E_GEO If all scan data could not be written.
47  PGS_S_SUCCESS Otherwise
48 
49 Externally Defined:
50  azimuth_index "GEO_global_arrays.h"
51  DETECTORS_QKM "GEO_geo.h"
52  DETECTORS_1KM "GEO_geo.h"
53  GFLAGS "GEO_product.h"
54  HEIGHT_OFFSET "GEO_product.h"
55  HT_IDX "GEO_global_arrays.h"
56  INVALID_INPUT_DATA "GEO_geo.h"
57  LAND_SEAMASK "GEO_product.h"
58  LAT_FVALUE "GEO_geo.h"
59  LAT_IDX "GEO_global_arrays.h"
60  LATITUDE "GEO_product.h"
61  LON_IDX "GEO_global_arrays.h"
62  LONG_FVALUE "GEO_geo.h"
63  LONGITUDE "GEO_product.h"
64  MAPIOK "mapi.h"
65  MAX_FRAMES "GEO_geo.h"
66  MAX_SCAN_NUMBER "GEO_geo.h"
67  MAX_UINT16_VAL "GEO_geo.h"
68  NO_ELLIPSE_INTERSECT "GEO_geo.h"
69  PGS_S_SUCCESS "PGS_SMF.h"
70  MODIS_E_BAD_INPUT_ARG "PGS_MODIS_35251.h"
71  MODIS_E_GEO "PGS_MODIS_35251.h"
72  RAD2DEG "GEO_geo.h"
73  RANGE_FVALUE "GEO_geo.h"
74  range_index "GEO_global_arrays.h"
75  SCAN_GRP "GEO_product.h"
76  SCAN_OFFSET "GEO_product.h"
77  SEN_AZIMUTH "GEO_product.h"
78  SEN_ZENITH "GEO_product.h"
79  SENSORAZIM_FVALUE "GEO_geo.h"
80  SENSORZEN_FVALUE "GEO_geo.h"
81  SOL_AZIMUTH "GEO_product.h"
82  SOL_ZENITH "GEO_product.h"
83  SOLARAZIM_FVALUE "GEO_geo.h"
84  SOLARZEN_FVALUE "GEO_geo.h"
85  TRACK_OFFSET "GEO_product.h"
86  z_angle_index "GEO_global_arrays.h"
87 
88 Called by:
89  GEO_write_one_scan
90 
91 Routines Called:
92  putMODISarray "mapi.h"
93  modsmf "smfio.h"
94 
95 !Revision History:
96  $Log: GEO_write_scan_data.c,v $
97  Revision 6.7 2014/08/01 21:38:36 jkuyper
98  Corrected landsea and waterpresent dimensions to actual maximum value.
99 
100  Revision 6.6 2011/03/08 20:21:28 kuyper
101  Corrected bug introduced in 6.1, by writing sensor and solar angles in
102  degrees, rather than radians.
103 
104  Revision 6.5 2011/02/18 22:03:04 kuyper
105  In order to Resolve feature request Bug 3446, changed to get landsea mask
106  directly, rather than through swath_elem, and to also get waterpresent.
107  Corrected declaration of parameters that point at input data.
108 
109  Revision 6.4 2010/12/15 23:19:20 kuyper
110  Changed to use *_IDX instead of *_index.
111  Corrected to set fillvalue for Height along with Latitude and Longitude.
112 
113  Revision 6.3 2010/06/18 20:49:36 kuyper
114  Corrected message about invalid input arguments.
115 
116  Revision 6.2 2009/06/12 16:21:48 kuyper
117  Corrected to write the entire scan of each high-resolution offset SDS.
118 
119  Revision 6.1 2009/05/28 21:29:20 xgeng
120  Changed MAX_SCAN_SAMPLE and MAX_DETECTORS to MAX_FRAMES and DETECTORS_1KM.
121  Changed num_samples to num_frames.
122  Changed to write high-resolution offsets, controlled by num_detectors;
123  all other SDS now use DETECTORS_1KM, instead.
124  Changed to reorganize and convert data at one time, avoiding redundant copy
125  that used to be stored in swath_elem.
126  Changed to return status codes.
127  The above code changes match with PDL revision 6.1 and 6.2.
128 
129  Xu Geng (xu.geng@saic.com)
130 
131  Revision 4.3 2004/03/11 00:08:29 kuyper
132  Corrected macro name.
133 
134  Revision 4.2 2003/10/30 23:52:40 kuyper
135  Corrected scaling of range.
136 
137  Revision 4.1 2003/08/15 20:01:50 vlin
138  Resolve DDTs MODxl01751: Don't scale fill values.
139 
140  Revision 3.1 2002/06/13 22:57:47 kuyper
141  Removed unnecessary NCSA acknowledgement.
142 
143  Revision 2.4 1998/02/08 22:31:59 jjb
144  Merged from V2.0 DAAC Delivery.
145 
146  5/25/95
147  Frederick S. Patt (patt@modis-xl.gsfc.nasa.gov)
148  Finished coding.
149 
150 Requirements:
151  PR03-F-4.3-1
152  PR03-F-4.3-1
153  PR03-I-1
154  PR03-I-3
155  PR03-S-1
156  PR03-S-2
157 
158 !Team-unique Header:
159 
160  This software is developed by the MODIS Science Data Support
161  Team for the National Aeronautics and Space Administration,
162  Goddard Space Flight Center, under contract NAS5-32373.
163 
164 References and Credits: None
165 
166 Design Notes: None
167 
168 !END
169 *******************************************************************************/
170 {
171  int obj, pixel, scanline, frame;
172  int objs = 0, ier, N_samp, EV_frames;
173  PGSt_SMF_status ret_val = PGS_S_SUCCESS;
174  uint8 gflags[DETECTORS_1KM*MAX_FRAMES];
176  int16 sensorazim[DETECTORS_1KM*MAX_FRAMES];
177  int16 sensorzen[DETECTORS_1KM*MAX_FRAMES];
178  int16 solarazim[DETECTORS_1KM*MAX_FRAMES];
179  int16 solarzen[DETECTORS_1KM*MAX_FRAMES];
181  static long int dims[2] = {DETECTORS_1KM, MAX_FRAMES};
182  static long int start[2] = {0L};
183  static long int hires_start[2] ;
184  static long int hires_dims[2];
185  int8 scan_offset[DETECTORS_QKM*SAMPLES_QKM];
186  int8 track_offset[DETECTORS_QKM*SAMPLES_QKM];
187  int8 height_offset[DETECTORS_QKM*SAMPLES_QKM];
188  uint8 landsea[DETECTORS_1KM*MAX_FRAMES];
189  uint8 waterpresent[DETECTORS_1KM*MAX_FRAMES];
190  float32 latit[DETECTORS_1KM*MAX_FRAMES];
191  float32 longit[DETECTORS_1KM*MAX_FRAMES];
192  char msgbuf[PGS_SMF_MAX_MSGBUF_SIZE];
193  char filefunc[] = __FILE__ ", GEO_write_scan_data";
194 
195  struct {
196  char *name; /*text string of the product file SDS object to write to. */
197  void *data; /* data to write to the SDS. */
198  long *start; /*Pointer to array of start indices */
199  long *dims; /*Pointer to array of dimensions */
200  } Scan_metadata[] = {
201  {LATITUDE, NULL, start, dims},
202  {LONGITUDE, NULL, start, dims},
203  {HEIGHT, NULL, start, dims},
204  {SEN_AZIMUTH, NULL, start, dims},
205  {SEN_ZENITH, NULL, start, dims},
206  {SOL_AZIMUTH, NULL, start, dims},
207  {SOL_ZENITH, NULL, start, dims},
208  {RANGE, NULL, start, dims},
209  {LAND_SEAMASK, NULL, start, dims},
210  {WATER_PRESENT, NULL, start, dims},
211  {GFLAGS, NULL, start, dims},
212  {SCAN_OFFSET, NULL, hires_start, hires_dims},
213  {TRACK_OFFSET, NULL, hires_start, hires_dims},
214  {HEIGHT_OFFSET, NULL, hires_start, hires_dims},
215  };
216 
217  if (geo_file == NULL || swath_elem == NULL ||
218  GEO_param == NULL || terrain_frame_position == NULL ||
219  frame_to_sensor == NULL || frame_solar_angles == NULL ||
220  frame_flags == NULL || frame_landsea == NULL ||
221  frame_waterpresent == NULL || hires_offsets == NULL ||
222  scan_number < 0 || scan_number >= MAX_SCAN_NUMBER)
223  {
224  sprintf(msgbuf, "swath_elem = %p, geo_file = %p, scan_number = %d\n"
225  "\tterrain_frame_position = %p, frame_to_sensor = %p\n"
226  "\tframe_solar_angles = %p, frame_flags = %p frame_landsea=%p\n"
227  "\frame_waterpresent = %p, thires_offsets = %p",
228  (void*)swath_elem, (void *)geo_file, scan_number,
229  (void*)terrain_frame_position, (void*)frame_to_sensor,
230  (void*)frame_solar_angles, (void*)frame_flags, (void*)frame_landsea,
231  (void*)frame_waterpresent, (void*)hires_offsets);
232  modsmf(MODIS_E_BAD_INPUT_ARG, msgbuf, filefunc);
233  return MODIS_E_BAD_INPUT_ARG;
234  }
235 
236  N_samp = GEO_param->geometry_params.N_samp[GEO_param->geometry_params.band_number];
237  if (N_samp < 1 || N_samp > 4 || swath_elem->num_frames < 0
238  || swath_elem->num_frames > MAX_FRAMES
239  || swath_elem->num_detectors <= 0
240  || swath_elem->num_detectors > DETECTORS_1KM) {
241  sprintf(msgbuf, "N_samp=%d, num_frames = %d, num_detectors = %d\n",
242  N_samp, swath_elem->num_frames, swath_elem->num_detectors);
243  modsmf(MODIS_E_BAD_INPUT_ARG, msgbuf, filefunc);
244  return MODIS_E_BAD_INPUT_ARG;
245  }
246 
247  if (swath_elem->num_frames == 0)
248  return PGS_S_SUCCESS;
249 
250  start[0] = (long)(scan_number * DETECTORS_1KM);
251  dims[1] = (long)swath_elem->num_frames;
252  EV_frames = swath_elem->num_frames;
253 
254  for(scanline = 0; scanline < DETECTORS_1KM; scanline++)
255  {
256  memcpy(&gflags[EV_frames*scanline], frame_flags[scanline], EV_frames);
257  for(frame = 0; frame < EV_frames; frame++)
258  {
259  pixel = EV_frames*scanline+frame;
260  latit[pixel] = terrain_frame_position[scanline][frame][LAT_IDX]*RAD2DEG;
261  longit[pixel] = terrain_frame_position[scanline][frame][LON_IDX]*RAD2DEG;
262  height[pixel] = (int16)floor(terrain_frame_position[scanline][frame][HT_IDX]+0.5);
263  landsea[pixel] = frame_landsea[scanline][frame];
264  waterpresent[pixel] = frame_waterpresent[scanline][frame];
265 
266  if(frame_to_sensor[scanline][frame][azimuth_index] == SENSORAZIM_FVALUE)
267  sensorazim[pixel] = SENSORAZIM_FVALUE;
268  else sensorazim[pixel] = (int16)floor(
269  frame_to_sensor[scanline][frame][azimuth_index]*RAD2DEG/GEO_param->angle_scale + 0.5);
270 
271  if(frame_to_sensor[scanline][frame][z_angle_index] == SENSORZEN_FVALUE)
272  sensorzen[pixel] = SENSORZEN_FVALUE ;
273  else sensorzen[pixel] = (int16)floor(
274  frame_to_sensor[scanline][frame][z_angle_index]*RAD2DEG/GEO_param->angle_scale+0.5);
275 
276  if(frame_to_sensor[scanline][frame][range_index] /
277  GEO_param->range_scale > MAX_UINT16_VAL)
279  else range[pixel] = (uint16)floor(
280  frame_to_sensor[scanline][frame][range_index]/GEO_param->range_scale + 0.5);
281 
282  if(frame_solar_angles[scanline][frame][azimuth_index] == SOLARAZIM_FVALUE)
283  solarazim[pixel] = SOLARAZIM_FVALUE;
284  else solarazim[pixel] = (int16)floor(
285  frame_solar_angles[scanline][frame][azimuth_index]*RAD2DEG/GEO_param->angle_scale + 0.5);
286 
287  if(frame_solar_angles[scanline][frame][z_angle_index] == SOLARZEN_FVALUE)
288  solarzen[pixel] = SOLARZEN_FVALUE ;
289  else solarzen[pixel] = (int16)floor(
290  frame_solar_angles[scanline][frame][z_angle_index]*RAD2DEG/GEO_param->angle_scale + 0.5);
291 
293  {
294  latit[pixel] = (float32)LAT_FVALUE;
295  longit[pixel] = (float32)LONG_FVALUE;
296  height[pixel] = (int8)HGHT_FVALUE;
297  }
298 
299  }
300  }
301 
302  if (!swath_elem->lat_qaflag){
303  Scan_metadata[objs].data = latit;
304  }
305  objs++;
306 
307  if (!swath_elem->lon_qaflag){
308  Scan_metadata[objs].data = longit;
309  }
310  objs++;
311 
312  if (!swath_elem->height_qaflag){
313  Scan_metadata[objs].data = height;
314  }
315  objs++;
316 
317  if (!swath_elem->sensorazimuth_qaflag){
318  Scan_metadata[objs].data = sensorazim;
319  }
320  objs++;
321 
322  if (!swath_elem->sensorzenith_qaflag){
323  Scan_metadata[objs].data = sensorzen;
324  }
325  objs++;
326 
327  if (!swath_elem->solarazimuth_qaflag){
328  Scan_metadata[objs].data = solarazim;
329  }
330  objs++;
331 
332  if (!swath_elem->solarzenith_qaflag){
333  Scan_metadata[objs].data = solarzen;
334  }
335  objs++;
336 
337  if (!swath_elem->range_qaflag){
338  Scan_metadata[objs].data = range;
339  }
340  objs++;
341 
342  if (!swath_elem->land_seamask_qaflag){
343  Scan_metadata[objs].data = landsea;
344  Scan_metadata[objs+1].data = waterpresent;
345  }
346  objs+=2;
347 
348  Scan_metadata[objs].data = gflags;
349  objs++;
350 
351  if(N_samp > 1) {
352  hires_start[0] = start[0] * N_samp;
353  hires_dims[0] = DETECTORS_1KM * N_samp;
354  hires_dims[1] = dims[1] * N_samp;
355  for(scanline = 0; scanline < hires_dims[0]; scanline++){
356  memcpy(&scan_offset[scanline*hires_dims[1]],
357  &hires_offsets[0][scanline], hires_dims[1]);
358  memcpy(&track_offset[scanline*hires_dims[1]],
359  &hires_offsets[1][scanline], hires_dims[1]);
360  memcpy(&height_offset[scanline*hires_dims[1]],
361  &hires_offsets[2][scanline], hires_dims[1]);
362  }
363  Scan_metadata[objs].data = scan_offset;
364  objs++;
365  Scan_metadata[objs].data = track_offset;
366  objs++;
367  Scan_metadata[objs].data = height_offset;
368  objs++;
369  }
370 
371  for (obj = 0; obj < objs; obj++){
372  if (Scan_metadata[obj].data != NULL) {
373  ier = putMODISarray(geo_file, Scan_metadata[obj].name, SCAN_GRP,
374  Scan_metadata[obj].start, Scan_metadata[obj].dims,
375  Scan_metadata[obj].data);
376  if (ier != MAPIOK){
377  sprintf(msgbuf, "putMODISarray(%s, %s)", geo_file->filename,
378  Scan_metadata[obj].name);
379  modsmf(MODIS_E_GEO, msgbuf, filefunc);
380  ret_val = MODIS_E_GEO;
381  }
382  }
383  }
384 
385  return ret_val;
386 }
#define SOL_ZENITH
Definition: GEO_product.h:235
integer, parameter int16
Definition: cubeio.f90:3
#define LAT_FVALUE
Definition: GEO_geo.h:147
#define SOLARZEN_FVALUE
Definition: GEO_geo.h:152
#define HEIGHT
Definition: GEO_product.h:231
#define SENSORAZIM_FVALUE
Definition: GEO_geo.h:150
#define L(lambda, T)
Definition: PreprocessP.h:185
#define SOL_AZIMUTH
Definition: GEO_product.h:236
#define NULL
Definition: decode_rs.h:63
#define MODIS_E_BAD_INPUT_ARG
#define MAX_FRAMES
Definition: GEO_geo.h:79
#define LONGITUDE
Definition: GEO_product.h:229
uint8 sensorzenith_qaflag
Definition: GEO_output.h:119
const unsigned char NO_ELLIPSE_INTERSECT
uint8 land_seamask_qaflag
Definition: GEO_output.h:125
#define WATER_PRESENT
Definition: GEO_product.h:238
@ HT_IDX
#define SCAN_GRP
Definition: GEO_product.h:149
#define SENSORZEN_FVALUE
Definition: GEO_geo.h:149
uint8 solarzenith_qaflag
Definition: GEO_output.h:121
@ azimuth_index
#define LONG_FVALUE
Definition: GEO_geo.h:146
#define GFLAGS
Definition: GEO_product.h:239
#define MODIS_E_GEO
#define MAX_UINT16_VAL
Definition: GEO_geo.h:175
#define HEIGHT_OFFSET
Definition: GEO_product.h:244
#define SEN_AZIMUTH
Definition: GEO_product.h:233
unsigned short N_samp[MAX_BAND_NUMBER_PLUS_ONE]
#define HGHT_FVALUE
Definition: GEO_geo.h:148
focal_plane_geometry_struct geometry_params
#define RAD2DEG
Definition: GEO_geo.h:173
#define TRACK_OFFSET
Definition: GEO_product.h:243
#define SEN_ZENITH
Definition: GEO_product.h:232
this program makes no use of any feature of the SDP Toolkit that could generate such a then geolocation is calculated at that and then aggregated up to Resolved feature request Bug by adding three new int8 SDSs for each high resolution pixel
Definition: HISTORY.txt:192
#define DETECTORS_1KM
Definition: GEO_geo.h:85
PGSt_SMF_status GEO_write_scan_data(MODFILE *const geo_file, int const scan_number, swath_elem_struct const *swath_elem, GEO_param_struct const *GEO_param, double terrain_frame_position[][MAX_FRAMES][3], double frame_to_sensor[][MAX_FRAMES][3], double frame_solar_angles[][MAX_FRAMES][2], uint8 frame_flags[][MAX_FRAMES], uint8 frame_landsea[][MAX_FRAMES], uint8 frame_waterpresent[][MAX_FRAMES], int8 hires_offsets[][DETECTORS_QKM][SAMPLES_QKM])
no change in intended resolving MODur00064 Corrected handling of bad ephemeris attitude data
Definition: HISTORY.txt:356
@ range_index
@ LON_IDX
#define RANGE
Definition: GEO_product.h:234
@ LAT_IDX
const int MAX_SCAN_NUMBER
uint8 sensorazimuth_qaflag
Definition: GEO_output.h:118
@ z_angle_index
const unsigned char INVALID_INPUT_DATA
#define SAMPLES_QKM
Definition: GEO_geo.h:83
#define LAND_SEAMASK
Definition: GEO_product.h:237
#define SCAN_OFFSET
Definition: GEO_product.h:242
#define DETECTORS_QKM
Definition: GEO_geo.h:87
#define LATITUDE
Definition: GEO_product.h:230
#define SOLARAZIM_FVALUE
Definition: GEO_geo.h:153
#define RANGE_FVALUE
Definition: GEO_geo.h:151
uint8 solarazimuth_qaflag
Definition: GEO_output.h:120