OB.DAAC Logo
NASA Logo
Ocean Color Science Software

ocssw V2022
b128_msk_get.c
Go to the documentation of this file.
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <string.h>
4 #include "l12_proto.h"
5 
6 #define NITEMPTR 1024 * 64
7 #define BOX_MAX 100
8 #define MAX_PIX_PER_SCENE MAXPIX*20000
9 
10 static FILE *stream[2] = {NULL, NULL};
11 
12 typedef short ptr_arr_t[NITEMPTR];
13 static ptr_arr_t* ptr_arr;
14 
15 static int access_cnt[2] = {0, 0};
16 static int last_box_num[2] = {-1, -1};
17 static int boxes_active[2] = {0, 0};
18 
19 /* this is an array of structures to hold info on each 1 degree box
20  recently needed */
21 struct box_info_str {
22  int box_num; /* box number stored in this slot */
23  int last_access_cnt; /* last access count for this boxes data */
24  unsigned short *box_ptr; /* pointer to the box's data */
25 };
26 
27 typedef struct box_info_str box_info_t[BOX_MAX];
28 static box_info_t* box_info;
29 
30 int b128_msk_init(char *landfile, int msknum)
31 /*******************************************************************
32 
33  b128_msk_init
34 
35  purpose: initialize the 218 x 128 per degree resolution processing
36  to get the a mask
37 
38  Returns type: int - 0 is good, else an open or read error
39 
40  Parameters: (in calling order)
41  Type Name I/O Description
42  ---- ---- --- -----------
43  char * landfile I name of mask file to use
44  int msknum I number of the mask (0 or 1)
45 
46  Modification history:
47  Programmer Date Description of change
48  ---------- ---- ---------------------
49  W. Robinson 8-Oct-1997 Original development
50  W. Robinson 19-Dec-1997 adapt to use 2 mask files
51 
52  *******************************************************************/ {
53  short rec_arr[1024];
54 
55  // allocate memory
56  if (!box_info) {
57  box_info = (box_info_t*) allocateMemory(2 * sizeof (box_info_t), "box_info");
58  ptr_arr = (ptr_arr_t*) allocateMemory(2 * sizeof (ptr_arr_t), "ptr_arr");
59  }
60 
61 
62  /*
63  * make sure valid mask # is input
64  */
65  if (msknum < 0 || msknum > 1) {
66  fprintf(stderr, "b128_msk_init: Fatal error. only mask 0 or 1 can be used\n");
67  fprintf(stderr, " current mask: %d\n", msknum);
68  fprintf(stderr, "Exiting\n");
69  return -1;
70  }
71  /*
72  * open the mask file
73  */
74  if ((stream[msknum] = fopen(landfile, "rb")) == NULL) {
75  fprintf(stderr, "b128_msk_init: Fatal error. failed to open mask file # %d:\n",
76  msknum);
77  fprintf(stderr, " '%s'\n", landfile);
78  fprintf(stderr, "Exiting\n");
79  return -1;
80  }
81  /*
82  * read in first record and check it out
83  */
84  if (fread(rec_arr, sizeof (short), 1024, stream[msknum]) != 1024) {
85  fprintf(stderr, "b128_msk_init: read error for first record of file # %d:\n",
86  msknum);
87  fprintf(stderr, " '%s'\n", landfile);
88  fprintf(stderr, "Exiting\n");
89  return -1;
90  }
91 
92  if (endianess() == 1)
93  swapc_bytes((char *) rec_arr, 2, 1024);
94 
95  if (rec_arr[0] != 128 || rec_arr[2] != 2048 ||
96  rec_arr[3] != -180 || rec_arr[4] != 180 ||
97  rec_arr[5] != -90 || rec_arr[6] != 90) {
98  fprintf(stderr, "b128_msk_init: header record does not match expected values\n");
99  fprintf(stderr, " for mask # %d\n", msknum);
100  fprintf(stderr, "\nvalue expected read\n");
101  fprintf(stderr, "0 128 %d\n", rec_arr[0]);
102  fprintf(stderr, "2 2048 %d\n", rec_arr[2]);
103  fprintf(stderr, "3 -180 %d\n", rec_arr[3]);
104  fprintf(stderr, "4 180 %d\n", rec_arr[4]);
105  fprintf(stderr, "5 -90 %d\n", rec_arr[5]);
106  fprintf(stderr, "6 90 %d\n\n", rec_arr[6]);
107  fprintf(stderr, "Exiting\n");
108  return -1;
109  }
110  /*
111  * read the next 64 1024 short records as pointers to the state
112  * of the 1 degree box
113  */
114  if (fread(ptr_arr[msknum], sizeof (short), NITEMPTR, stream[msknum]) !=
115  NITEMPTR) {
116  fprintf(stderr, "b128_msk_init: read error for pointer array of file:\n");
117  fprintf(stderr, " '%s'\n", landfile);
118  fprintf(stderr, " mask # %d\n", msknum);
119  fprintf(stderr, "Exiting\n");
120  return -1;
121  }
122 
123  if (endianess() == 1)
124  swapc_bytes((char *) ptr_arr[msknum], 2, NITEMPTR);
125 
126  /*
127  * initialize some items
128  */
129  access_cnt[msknum] = 0; /* current count of mask accesses in the program */
130  boxes_active[msknum] = 0; /* # boxes read into the storage structure */
131 
132  return 0;
133 }
134 
135 int b128_msk_init_(char *flandfile, int *msknum, int len)
136 /*******************************************************************
137 
138  b128_msk_init_
139 
140  purpose: fortran interface for b128_msk_init
141 
142  Returns type: int - 0 is good, else an open or read error
143 
144  Calling sequence from fortran:
145 
146  iret = b128_msk_init( landfile, msknum )
147 
148  Parameters: (in calling order)
149  Type Name I/O Description
150  ---- ---- --- -----------
151  char * landfile I name of land mask file to use
152  int * msknum I mask number to use (0 or 1 )
153  int len I length that is passed with any
154  char string from fortran
155 
156  Modification history:
157  Programmer Date Description of change
158  ---------- ---- ---------------------
159  W. Robinson 8-Oct-1997 Original development
160  W. Robinson 19-Dec-1997 adapt to use 2 mask files
161 
162  *******************************************************************/ {
163  char landfile[400];
164  int mnum;
165 
166  if (len > 399) len = 399;
167  /*
168  * the usage in anly has a char*1 mask file array, so use this
169  * to get around that case (yuch)
170  */
171  if (len <= 1) {
172  strcpy(landfile, flandfile);
173  } else {
174  strncpy(landfile, flandfile, len);
175  strtok(landfile, " ");
176  }
177 
178  mnum = *msknum;
179 
180  return b128_msk_init(landfile, mnum);
181 }
182 
183 int b128_msk_get(float lat, float lon, int msknum)
184 /*******************************************************************
185 
186  b128_msk_get
187 
188  purpose: For an incoming latitude, longitude find if it is over
189  mask or not using the 128 by 128 / degree mask file
190 
191  Returns type: int - 1 for mask on, 0 for mask off, -1 for problem
192 
193  Parameters: (in calling order)
194  Type Name I/O Description
195  ---- ---- --- -----------
196  float lat I latitude of point from
197  -90. to 90.
198  float lon I longitudeof point from
199  -180 to 180.
200  int msknum I mask to use ( 0 or 1 )
201 
202  Modification history:
203  Programmer Date Description of change
204  ---------- ---- ---------------------
205  W. Robinson 8-Oct-1997 Original development
206  W. Robinson 19-Dec-1997 adapt to use 2 mask files
207 
208  *******************************************************************/ {
209  int land_fl, box_num, box_index, low_access_cnt,
210  low_access_index, i, box_wd, box_bit;
211  float lat_off, lon_off;
212  unsigned short mask[16] = {0x8000, 0x4000, 0x2000, 0x1000,
213  0x800, 0x400, 0x200, 0x100,
214  0x80, 0x40, 0x20, 0x10,
215  0x8, 0x4, 0x2, 0x1};
216  static int last_box_index[2];
217  /* declare subroutines */
218  int b128_box_num(float, float, float *, float *);
219  int b128_wd_bit(float, float, int *, int *);
220 
221  /*
222  * check mask # for validity
223  */
224  if (msknum < 0 || msknum > 1) {
225  fprintf(stderr, "b128_msk_init: Fatal error. only mask 0 or 1 can be used\n");
226  fprintf(stderr, " current mask: %d\n", msknum);
227  fprintf(stderr, "Exiting\n");
228  return -1;
229  }
230  /*
231  * check that b128_msk_init was called - the stream should be non-null
232  */
233  access_cnt[msknum]++; /* increment count of times called */
234 
235  if (access_cnt[msknum] >= MAX_PIX_PER_SCENE) {
236  printf("b128_msk_get: Pixels Per Scene Count Exceeded.\n");
237  exit(1);
238  }
239 
240  if (stream[msknum] == NULL) {
241  fprintf(stderr, "b128_msk_get: routine b128_msk_init not called yet\n");
242  fprintf(stderr, " for mask # %d\n", msknum);
243  fprintf(stderr, "Exiting\n");
244  land_fl = -1;
245  return land_fl;
246  }
247  /*
248  * get the box number for this lat, lon
249  */
250  box_num = b128_box_num(lat, lon, &lat_off, &lon_off);
251  /*
252  * maybe the box is all mask or non-mask and we can just return that info
253  */
254  if (*(ptr_arr[msknum] + box_num) < 2) {
255  land_fl = *(ptr_arr[msknum] + box_num);
256  } else {
257  /*
258  * the box contains a mix of land, water. see if we're looking at last box
259  */
260  if (box_num == last_box_num[msknum]) {
261  box_index = last_box_index[msknum]; /* index to locally stored box info */
262  } else {
263  /*
264  * not latest box, it still may be in another array position
265  */
266  box_index = -1;
267  low_access_cnt = MAX_PIX_PER_SCENE; /* while searching, record the lowest */
268  low_access_index = -1; /* access count and its location */
269 
270  for (i = 0; i < boxes_active[msknum]; i++) {
271  if (box_info[msknum][i].box_num == box_num) {
272  /*
273  * we found the box we need in array
274  */
275  box_index = i;
276  box_info[msknum][i].last_access_cnt = access_cnt[msknum];
277  break;
278  }
279  if (box_info[msknum][i].last_access_cnt < low_access_cnt) {
280  low_access_cnt = box_info[msknum][i].last_access_cnt;
281  low_access_index = i; /* record least recently used updated */
282  }
283  }
284 
285  /*
286  * if we didn't find the box in the struct array, set one up
287  */
288  if (box_index == -1) {
289  /*
290  * first case: add a box to the array in an empty slot
291  */
292  if (boxes_active[msknum] < BOX_MAX - 1) {
293  boxes_active[msknum]++;
294  box_index = boxes_active[msknum] - 1;
295  box_info[msknum][box_index].box_ptr =
296  (unsigned short *) malloc(1024 * sizeof ( short));
297  /* for debug / info
298  printf( "Incrementing boxes_active to %d\n", boxes_active );
299  printf( " lat: %f lon: %f\n", lat, lon );
300  */
301  } /*
302  * 2nd case is to re-use the least used array location
303  */
304  else {
305  box_index = low_access_index;
306  /* for debug / info
307  printf( "Re-using box index %d\n", box_index );
308  printf( " lat: %f lon: %f\n", lat, lon );
309  */
310  }
311  /*
312  * in either case, read in the proper record into the slot
313  */
314  box_info[msknum][box_index].box_num = box_num;
315  box_info[msknum][box_index].last_access_cnt = access_cnt[msknum];
316  if (fseek(stream[msknum],
317  ptr_arr[msknum][box_num] * 1024 * sizeof ( short), SEEK_SET)
318  != 0) {
319  fprintf(stderr, "b128_msk_get: Failure on mask file record seek\n");
320  fprintf(stderr, " record # %d mask # %d\n",
321  ptr_arr[msknum][ box_num ], msknum);
322  fprintf(stderr, " Exiting\n");
323  land_fl = -1;
324  } else {
325  if (fread(box_info[msknum][box_index].box_ptr, sizeof ( short),
326  1024, stream[msknum]) != 1024) {
327  fprintf(stderr, "b128_msk_get: Failure on mask record read\n");
328  fprintf(stderr, " record # %d mask # %d\n",
329  ptr_arr[msknum][ box_num ], msknum);
330  fprintf(stderr, " Exiting\n");
331  land_fl = -1;
332  }
333 
334  if (endianess() == 1)
335  swapc_bytes((char *) box_info[msknum][box_index].box_ptr, 2, 1024);
336 
337 
338  }
339  }
340  }
341  /*
342  * we have the box, get the exact word and bit to extract
343  */
344  b128_wd_bit(lat_off, lon_off, &box_wd, &box_bit);
345  land_fl = ((*(box_info[msknum][ box_index ].box_ptr + box_wd) &
346  mask[ box_bit ]) == 0) ? 0 : 1;
347  last_box_index[msknum] = box_index;
348  last_box_num[msknum] = box_num;
349  }
350  return land_fl;
351 }
352 
353 int b128_msk_get_(float *flat, float *flon, int *msknum)
354 /*******************************************************************
355 
356  b128_msk_get_
357 
358  purpose: fortran interface for b128_msk_get
359 
360  Returns type: int - 1 for mask, 0 for no mask
361 
362  Calling sequence from fortran:
363 
364  lnd_flg = b128_msk_get( flat, flon, msknum )
365 
366  Parameters: (in calling order)
367  Type Name I/O Description
368  ---- ---- --- -----------
369  float * flat I latitude
370  float * flon I longitude
371  int * msknum I mask # to get (0 or 1)
372 
373  Modification history:
374  Programmer Date Description of change
375  ---------- ---- ---------------------
376  W. Robinson 8-Oct-1997 Original development
377  W. Robinson 19-Dec-1997 adapt to use 2 mask files
378 
379  *******************************************************************/ {
380  float lat, lon;
381  int mnum;
382 
383  lat = *flat;
384  lon = *flon;
385  mnum = *msknum;
386 
387  return b128_msk_get(lat, lon, mnum);
388 }
#define BOX_MAX
Definition: b128_msk_get.c:7
int b128_msk_get_(float *flat, float *flon, int *msknum)
Definition: b128_msk_get.c:353
void * allocateMemory(size_t numBytes, const char *name)
Definition: allocateMemory.c:7
#define NULL
Definition: decode_rs.h:63
int b128_wd_bit(float lat_off, float lon_off, int *box_wd, int *box_bit)
Definition: b128_wd_bit.c:3
float * lat
int last_access_cnt
Definition: b128_msk_get.c:23
int endianess(void)
determine endianess
Definition: endianess.c:10
int swapc_bytes(char *in, int nbyte, int ntime)
Definition: swapc_bytes.c:4
#define MAX_PIX_PER_SCENE
Definition: b128_msk_get.c:8
#define NITEMPTR
Definition: b128_msk_get.c:6
a context in which it is NOT documented to do so subscript which cannot be easily calculated when extracting TONS attitude data from the Terra L0 files Corrected several defects in extraction of entrained ephemeris and and as HDF file for both the L1A and Geolocation enabling retrieval of South Polar DEM data Resolved Bug by changing to opent the geolocation file only after a successful read of the L1A and also by checking for fatal errors from not restoring C5 and to report how many of those high resolution values were water in the new WaterPresent SDS Added valid_range attribute to Land SeaMask Changed to bilinearly interpolate the geoid_height to remove artifacts at one degree lines Made corrections to const qualification of pointers allowed by new version of M API library Removed casts that are no longer for same not the geoid Corrected off by one error in calculation of high resolution offsets Corrected parsing of maneuver list configuration parameter Corrected to set Height SDS to fill values when geolocation when for elevation and land water mask
Definition: HISTORY.txt:114
int b128_msk_init(char *landfile, int msknum)
Definition: b128_msk_get.c:30
unsigned short * box_ptr
Definition: b128_msk_get.c:24
int b128_box_num(float lat, float lon, float *lat_off, float *lon_off)
Definition: b128_box_num.c:3
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 and prod_ix set to PARAM_TYPE_INT name_prefix is compared with the beginning of the product name If name_suffix is not empty the it must match the end of the product name The characters right after the prefix are read as an integer and prod_ix is set to that number strncpy(l2prod->name_prefix, "myprod", UNITLEN)
float * lon
short ptr_arr_t[NITEMPTR]
Definition: b128_msk_get.c:12
int b128_msk_get(float lat, float lon, int msknum)
Definition: b128_msk_get.c:183
int i
Definition: decode_rs.h:71
int b128_msk_init_(char *flandfile, int *msknum, int len)
Definition: b128_msk_get.c:135
How many dimensions is the output array Default is Not sure if anything above will work correctly strcpy(l2prod->title, "no title yet")