OB.DAAC Logo
NASA Logo
Ocean Color Science Software

ocssw V2022
brightness.c
Go to the documentation of this file.
1 #include <sys/types.h>
2 #include <unistd.h>
3 
4 /* ============================================================================ */
5 /* module brightness.c - convert observed IR radiance to temperature */
6 /* */
7 /* Written By: B. Franz, NASA/SIMBIOS, August 2003. */
8 /* */
9 /* Generalized for other sensors, B. Franz, 12/2010 */
10 /* ============================================================================ */
11 
12 #include "l1.h"
13 #include <hdf.h>
14 #include <mfhdf.h>
15 
16 #define NBTDIMS 3
17 #define NBTTABMAX 100
18 #define NBTDETMAX 20
19 #define NBTBANDMAX 10
20 
21 static int16 ntab;
22 static int16 ndet;
23 static int16 nbnd;
24 
25 static float radtab [NBTBANDMAX][NBTDETMAX][NBTTABMAX];
26 static float temptab [NBTBANDMAX][NBTDETMAX][NBTTABMAX];
27 static float radinc [NBTBANDMAX][NBTDETMAX];
28 static int16 uselog [NBTBANDMAX];
29 
30 /* ----------------------------------------------------------------------------------- */
31 /* read_bt_table() - reads the radiance to temperature HDF file */
32 /* */
33 /* B. Franz, SAIC, August 2003. */
34 
35 /* ----------------------------------------------------------------------------------- */
36 int read_bt_table(char *filename, int nbands, int ndets) {
37  int32 sd_id;
38  int32 sds_id;
39  int32 status;
40  int32 rank;
41  int32 nt;
42  int32 nattrs;
43  int32 dims [H4_MAX_VAR_DIMS];
44  int32 start [NBTDIMS] = {0, 0, 0};
45  int32 end [NBTDIMS] = {1, 1, 1};
46  char name [H4_MAX_NC_NAME] = "";
47  char sdsname[H4_MAX_NC_NAME] = "";
48 
49  int ibnd, idet, itab;
50 
51 
52  if (strcmp(filename, "") == 0) {
53  printf("\nNo brightness temperature conversion provided for this sensor.\n");
54  return (1);
55  }
56 
57  if (want_verbose)
58  printf("Loading radiance to brightness temperature from %s\n", filename);
59 
60  // Open the file
61 
62  sd_id = SDstart(filename, DFACC_RDONLY);
63  if (sd_id == FAIL) {
64  fprintf(stderr, "-E- %s line %d: SDstart(%s, %d) failed.\n",
65  __FILE__, __LINE__, filename, DFACC_RDONLY);
66  return (1);
67  }
68 
69  // Get dimension attributes
70 
71  status = SDreadattr(sd_id, SDfindattr(sd_id, "Number of Bands"), &nbnd);
72  if (status != 0) {
73  status = SDreadattr(sd_id, SDfindattr(sd_id, "number_of_bands"), &nbnd);
74  if (status != 0) {
75  printf("-E- %s Line %d: Error reading global attribute %s from %s.\n",
76  __FILE__, __LINE__, "Number of Bands", filename);
77  exit(1);
78  }
79  }
80  status = SDreadattr(sd_id, SDfindattr(sd_id, "Number of Detectors"), &ndet);
81  if (status != 0) {
82  status = SDreadattr(sd_id, SDfindattr(sd_id, "number_of_detectors"), &ndet);
83  if (status != 0) {
84 
85  printf("-E- %s Line %d: Error reading global attribute %s from %s.\n",
86  __FILE__, __LINE__, "Number of Detectors", filename);
87  exit(1);
88  }
89  }
90  status = SDreadattr(sd_id, SDfindattr(sd_id, "Number of Radiance Levels"), &ntab);
91  if (status != 0) {
92  status = SDreadattr(sd_id, SDfindattr(sd_id, "number_of_radiance_levels"), &ntab);
93  if (status != 0) {
94 
95  printf("-E- %s Line %d: Error reading global attribute %s from %s.\n",
96  __FILE__, __LINE__, "Number of Radiance Levels", filename);
97  exit(1);
98  }
99  }
100  if (ntab > NBTTABMAX || nbnd > NBTBANDMAX || ndet > NBTDETMAX) {
101  printf("-E- %s Line %d: BT table dimensions exceed max allowable (%d %d %d).\n",
102  __FILE__, __LINE__, ntab, nbnd, ndet);
103  exit(1);
104  }
105  if (nbnd != nbands || ndet > ndets) {
106  printf("-E- %s Line %d: BT table dimensions does not match sensor attributes (%d %d).\n",
107  __FILE__, __LINE__, nbnd, ndet);
108  exit(1);
109  }
110 
111  // Read log flag
112 
113  strcpy(sdsname, "Uselog");
114  sds_id = SDselect(sd_id, SDnametoindex(sd_id, sdsname));
115  status = SDgetinfo(sds_id, name, &rank, dims, &nt, &nattrs);
116  status = SDreaddata(sds_id, start, NULL, dims, (VOIDP) uselog);
117  if (status != 0) {
118  printf("-E- %s: Error reading SDS %s from %s.\n", __FILE__, sdsname, filename);
119  exit(1);
120  }
121  status = SDendaccess(sds_id);
122 
123  // Read radiance levels
124 
125  strcpy(sdsname, "Radiances");
126  sds_id = SDselect(sd_id, SDnametoindex(sd_id, sdsname));
127  status = SDgetinfo(sds_id, name, &rank, dims, &nt, &nattrs);
128  for (ibnd = 0; ibnd < nbnd; ibnd++) for (idet = 0; idet < ndet; idet++) for (itab = 0; itab < ntab; itab++) {
129  start[0] = ibnd;
130  start[1] = idet;
131  start[2] = itab;
132  status = SDreaddata(sds_id, start, NULL, end, (VOIDP) & radtab[ibnd][idet][itab]);
133  if (status != 0) {
134  printf("-E- %s: Error reading %s from %s.\n", __FILE__, sdsname, filename);
135  exit(1);
136  }
137  }
138  status = SDendaccess(sds_id);
139 
140  // Read temperature levels
141 
142  strcpy(sdsname, "Temperatures");
143  sds_id = SDselect(sd_id, SDnametoindex(sd_id, sdsname));
144  status = SDgetinfo(sds_id, name, &rank, dims, &nt, &nattrs);
145  for (ibnd = 0; ibnd < nbnd; ibnd++) for (idet = 0; idet < ndet; idet++) for (itab = 0; itab < ntab; itab++) {
146  start[0] = ibnd;
147  start[1] = idet;
148  start[2] = itab;
149  status = SDreaddata(sds_id, start, NULL, end, (VOIDP) & temptab[ibnd][idet][itab]);
150  if (status != 0) {
151  printf("-E- %s: Error reading %s from %s.\n", __FILE__, sdsname, filename);
152  exit(1);
153  }
154  }
155  status = SDendaccess(sds_id);
156 
157  // Close file
158 
159  SDend(sd_id);
160 
161  return (0);
162 }
163 
164 /* ----------------------------------------------------------------------------------- */
165 /* radiance2bt() - interpolates brightness temps from table . */
166 /* */
167 /* B. Franz, SAIC, August 2003. */
168 
169 /* ----------------------------------------------------------------------------------- */
170 void radiance2bt(l1str *l1rec, int resolution) {
171  static int firstCall = 1;
172 
173  int32_t nbands = l1rec->l1file->nbandsir;
174  int32_t ndets = l1rec->l1file->ndets;
175  int32_t id, ip, ib, ipb;
176  int32_t i;
177  float a;
178  float rad;
179 
180  // on first call, load the table
181  if (firstCall) {
182  firstCall = 0;
183  if (l1_input->btfile[0]) {
184  if (read_bt_table(l1_input->btfile, nbands, ndets) != 0) {
185  printf("Error loading brightness temperature table.\n");
186  exit(1);
187  }
188  } else {
189  printf("Brightness temperature file not specified.");
190  exit(1);
191  }
192 
193  for (ib = 0; ib < nbands; ib++)
194  for (id = 0; id < ndets; id++)
195  radinc[ib][id] = radtab[ib][id][1] - radtab[ib][id][0];
196  }
197 
198  // modis-specific handling for dets per resolution: needs generalization
199  switch (resolution) {
200  case 250: id = l1rec->detnum / 4;
201  break;
202  case 500: id = l1rec->detnum / 2;
203  break;
204  default: id = l1rec->detnum / 1;
205  break;
206  }
207 
208  for (ip = 0; ip < l1rec->npix; ip++)
209  for (ib = 0; ib < nbands; ib++) {
210 
211  ipb = ip * NBANDSIR + ib;
212 
213  if (!isfinite(l1rec->Ltir[ipb]) || l1rec->Ltir[ipb] <= 0.0) {
214  l1rec->Bt[ipb] = BT_LO;
215  continue;
216  }
217 
218  rad = l1rec->Ltir[ipb]*10.0; /* radiance in W/m^2/nm/sr */
219 
220  if (uselog[ib])
221  rad = log10(rad);
222 
223  if (rad <= radtab[ib][id][0])
224  l1rec->Bt[ipb] = BT_LO;
225  else if (rad >= radtab[ib][id][ntab - 1])
226  l1rec->Bt[ipb] = BT_HI;
227  else {
228  i = (int32_t) ((rad - radtab[ib][id][0]) / radinc[ib][id]);
229  a = (rad - radtab[ib][id][i]) / (radtab[ib][id][i + 1] - radtab[ib][id][i]);
230  l1rec->Bt[ipb] = temptab[ib][id][i] + a * (temptab[ib][id][i + 1] - temptab[ib][id][i]);
231  l1rec->Bt[ipb] -= 273.15;
232  }
233  }
234 }
integer, parameter int16
Definition: cubeio.f90:3
int status
Definition: l1_czcs_hdf.c:32
#define NBANDSIR
Definition: filehandle.h:23
#define FAIL
Definition: ObpgReadGrid.h:18
#define NULL
Definition: decode_rs.h:63
this program makes no use of any feature of the SDP Toolkit that could generate such a then geolocation is calculated at that resolution
Definition: HISTORY.txt:188
read l1rec
int nbnd
Definition: get_cmp.c:29
#define BT_HI
Definition: l1.h:55
int read_bt_table(char *filename, int nbands, int ndets)
Definition: brightness.c:36
l1_input_t * l1_input
Definition: l1_options.c:9
int want_verbose
char filename[FILENAME_MAX]
Definition: atrem_corl1.h:122
#define NBTDETMAX
Definition: brightness.c:18
int32_t nbands
Definition: common.h:9
void radiance2bt(l1str *l1rec, int resolution)
Definition: brightness.c:170
#define NBTDIMS
Definition: brightness.c:16
#define NBTBANDMAX
Definition: brightness.c:19
Extra metadata that will be written to the HDF4 file l2prod rank
#define BT_LO
Definition: l1.h:54
int i
Definition: decode_rs.h:71
How many dimensions is the output array Default is Not sure if anything above will work correctly strcpy(l2prod->title, "no title yet")
#define NBTTABMAX
Definition: brightness.c:17
PGE01 indicating that PGE02 PGE01 V6 for and PGE01 V2 for MOD03 were used to produce the granule By convention adopted in all MODIS Terra PGE02 code versions are The fourth digit of the PGE02 version denotes the LUT version used to produce the granule The source of the metadata environment variable ProcessingCenter was changed from a QA LUT value to the Process Configuration A sign used in error in the second order term was changed to a
Definition: HISTORY.txt:424