OB.DAAC Logo
NASA Logo
Ocean Color Science Software

ocssw V2022
get_cmp.c
Go to the documentation of this file.
1 # include <stdlib.h>
2 # include <stdio.h>
3 #include "l12_proto.h"
4 #include <netcdf.h>
5 #include "met_cvt.h"
6 #include "scene_meta.h"
7 
8 extern void ch_cld_sci_( float *, int *, unsigned char *, int *,
9  int32_t *, int *, int *, char * );
10 /*
11  routine get_cmp.c - Made from tst_cld_sci.c - this will be a stub to
12  read the small chimaera data set and call the chimaera code to run
13  a small set of pixels through the science code.
14 
15  This will first demonstrate the union of l2gen and the chimaera code
16 
17  This is the c portion, which reads in the data from a netcdf file
18  wc_file.nc and set up the data to pass to the f90 code: ch_cld_sci.f90
19 
20  I have also put in 2 netcdf convenience routines based on the ncio_grab_f_ds
21  in the l2gen src area file ncio.c
22 */
23 
24 /* this must be global or the f90 won't see it */
25 struct
26  {
27  int npix; /* array sizes */
28  int nlin;
29  int nbnd;
32  int scan; /* mainly used for reading same data */
33  int st_samp; /* from MODIS L2 cloud file */
34  int g_year; /* the granule year */
35  int g_day; /* the granule day-of-year */
36  } dim_ctl_;
37 
38  static int32_t cur_cmp_rec = -1;
39 
40 int get_cmp( l2str *l2rec, int prodnum, float prod[])
41 /*
42 get_cmp will just initiate the derivation of cloud microphysical properties
43 (CMP) for the line if we haven't done so already. Then, it will pass back the
44 proper property array for that line
45 
46  Parameters: (in calling order)
47  Type Name I/O Description
48  ---- ---- --- -----------
49  l2str * l2rec I l2 record of data
50  int prodnum I Product ID to return
51  float [] prod O returned data - this storage is already allocated
52 
53 W. Robinson, SAIC, 4 Jan 2019
54 
55  W. Robinson, 14 Jun 2019 Add the cirrus reflectance data to the radiance set
56 */
57  {
58  int compute_cmp( l2str * );
59  void get_cmp_prod_( int *, float *, int * );
60  int ipix, n_prd;
61  /* if proc_cloud not set, error out */
62  if( input->proc_cloud == 0 ) {
63  printf( "%s, %d: Cloud products require the proc_cloud=1 set\n", __FILE__,
64  __LINE__ );
65  exit(1);
66  }
67  /* WDR this is just to force the call all the time */
68  if( l2rec->l1rec->iscan != cur_cmp_rec )
69  {
70  cur_cmp_rec = l2rec->l1rec->iscan;
71  if( compute_cmp( l2rec ) != 0 )
72  {
73  printf( "%s, %d: E - CMP computation failure\n", __FILE__, __LINE__ );
74  exit(1);
75  }
76  }
77  /*
78  * call get_cmp_prod to get the cmp desired
79  */
80  /* printf( "%s, %d: calling the get_cmp_prod\n", __FILE__, __LINE__ ); */
81  /* WDR this is awkward */
82 
83  n_prd = 1;
84  if( ( prodnum >= 480 ) && ( prodnum <= 482 ) ) n_prd = 10;
85  get_cmp_prod_( &prodnum, prod, &n_prd );
86  /*
87  * if any product value is < -900., set prodfail
88  * For now, limit to XXX_2100 prods - some better treatment for the
89  * different cmp products is needed going forward though
90  */
91  if( ( prodnum == CAT_CER_2100 ) || ( prodnum == CAT_COT_2100 ) ||
92  ( prodnum == CAT_COT_2100 ) )
93  {
94  for( ipix = 0; ipix < l2rec->l1rec->npix; ipix++ )
95  if( *( prod + ipix ) < -900 )
96  l2rec->l1rec->flags[ipix] |= PRODFAIL;
97  }
98  /*
99  * do the same for 1600 -> PRODWARN and 1621 -> NAVFAIL
100  */
101  if( ( prodnum == CAT_CER_1600 ) || ( prodnum == CAT_COT_1600 ) ||
102  ( prodnum == CAT_COT_1600 ) )
103  {
104  for( ipix = 0; ipix < l2rec->l1rec->npix; ipix++ )
105  if( *( prod + ipix ) < -900 )
106  l2rec->l1rec->flags[ipix] |= PRODWARN;
107  }
108  if( ( prodnum == CAT_CER_1621 ) || ( prodnum == CAT_COT_1621 ) ||
109  ( prodnum == CAT_COT_1621 ) )
110  {
111  for( ipix = 0; ipix < l2rec->l1rec->npix; ipix++ )
112  if( *( prod + ipix ) < -900 )
113  l2rec->l1rec->flags[ipix] |= NAVFAIL;
114  }
115  return(0);
116  }
117 
118 unsigned char *get_cmp_byt( l2str *l2rec, int prodnum )
119 /*
120 get_cmp_byt is like get_cmp but will provide the byte flag values
121 
122  Returns unsigned char array of the flag valueson the line
123 
124  Parameters: (in calling order)
125  Type Name I/O Description
126  ---- ---- --- -----------
127  l2str * l2rec I l2 record of data
128  int prodnum I Product ID to return
129 
130  W. Robinson, SAIC, 5 Aug 2019
131 
132 */
133  {
134  int compute_cmp( l2str * );
135  static unsigned char *bprod = NULL;
136  void get_cmp_byt_( int *, unsigned char * );
137  /* WDR this is just to force the call all the time */
138  if( l2rec->l1rec->iscan != cur_cmp_rec )
139  {
140  cur_cmp_rec = l2rec->l1rec->iscan;
141  if( compute_cmp( l2rec ) != 0 )
142  {
143  printf( "%s, %d: E - CMP computation failure\n", __FILE__, __LINE__ );
144  exit(1);
145  }
146  }
147 
148  if( bprod == NULL )
149  {
150  if( ( bprod = (unsigned char *)
151  malloc( l2rec->l1rec->npix * sizeof(unsigned char) ) ) == NULL )
152  {
153  printf( "%s, %d: E - unable to alocate byte storage\n",
154  __FILE__, __LINE__ );
155  exit(1);
156  }
157  }
158  /*
159  * call get_cmp_prod to get the cmp desired
160  */
161  /* printf( "%s, %d: calling the get_cmp_prod\n", __FILE__, __LINE__ ); */
162  get_cmp_byt_( &prodnum, bprod );
163 
164  return( bprod );
165  }
166 
167 int compute_cmp( l2str *l2rec )
168 /*
169  compute_cmp will derive the cloud microphysical properties
170 
171 */
172  {
173  /*
174  * set the inputs based on a netcdf file for the test
175  */
176  int set_cmp( l2str *, float **, int32_t *, int32_t **, int32_t *,
177  unsigned char **, int32_t * );
178  int32_t nfloat, nint32, nubyte;
179  static float *tdat;
180  static unsigned char *ubdat;
181  static int32_t *i32dat;
182  int sensor_id = l2rec->l1rec->l1file->sensorID;
183  /*
184  * Fill with data from the l1que
185  */
186  if( set_cmp( l2rec, &tdat, &nfloat, &i32dat, &nint32, &ubdat, &nubyte ) != 0 )
187  return(-1);
188  /*
189  * call the chimaera code
190  */
191  /* OK, call the f90 routine */
192  ch_cld_sci_( tdat, &nfloat, ubdat, &nubyte, i32dat, &nint32, &sensor_id,
193  input->cloud_hgt_file );
194 
195  return(0);
196  }
197 
198 int set_cmp( l2str *l2rec, float **tdat, int32_t *nfloat, int32_t **i32dat,
199  int32_t *nint32, unsigned char **ubdat, int32_t *nubyte )
200 /*
201  set_cmp will set up all the data required by the chimaera code from
202  the contents of the l1rec
203 
204 */
205  {
206  extern l1qstr l1que;
207  int mk_cmp_prof( float *, float *, float *, float *, float, float, float,
208  float, unsigned char *, unsigned char *, double *, double *, double *,
209  double * );
210 /* WDR **** temp to dummy the profile interp */
211  int mk_cmp_prof_dum( float *, float *, float *, float *, float, float, float,
212  float, unsigned char *, unsigned char *, double *, double *, double *,
213  double * );
214  int make_profile_101_( double * );
215  int32_t npix, nlin, nbnd_albedo, ctr_que,ibnd, iln, qln, ipx;
216  l1str *l1rec = l2rec->l1rec;
217  int32_t nbnd_ref, nbnd_emis, foff, foff2, uoff, uoff2, nbnd, sensor_id;
218  float *F0, rad, solz, out;
219  int32_t dbg_print, ix_bnd, force_oci, cld_missed;
220  int32_t ncmp_bnd = 15;
221  /* WDR a temp print routine for debug */
222  int profile_print( float *, unsigned char *, int32_t *, int32_t, int32_t,
223  int32_t, int32_t );
224 
225  /* some look-ups to id the type / location of the l2 rads relative to the
226  chimaera rads */
227  /* source for the chimaera rads: 1 reflective (Lt), 0 emmissive (Ltir)
228  and cirrus (rho_cirrus) */
229  int32_t ref_for_cmb[] = { 1, 1, 1, 1, 1, 1, 0, 2, 0, 0, 1, 0, 0, 1, 1 };
230  /* cloud band is in l1rec if 1, else 0 */
231  static char cmp_there[15];
232  /* index in Lt (ref) or Ltir (emis) (after # vis bands subtracted) */
233  static int32_t l1ix[15];
234  /* cloud band ideal wavelengths for MODIS (and any other inst to try) */
235  int32_t cld_wav_mod[] = { 645, 859, 1240, 1640, 2130, 930, 3750, 1375,
236  8550, 11000, 443, 12000, 13600, 469, 555 };
237  /* cloud bands for OCI (only) */
238  // int32_t cld_wav_oci[] = { 645, 859, 1250, 1615, 2130, 930, 3750, 1375,
239  // 8550, 11000, 443, 12000, 13600, 469, 555 };
240  /* 10 Sep 21 to match the waves for the Kerry Meyer table */
241  int32_t cld_wav_oci[] = { 665, 865, 1250, 1616, 2130, 930, 3750, 1375,
242  8550, 11000, 443, 12000, 13600, 469, 555 };
243  int32_t cld_wav[15];
244  /* OCI bands available (for simulation) */
245  int32_t oci_bnd_avail[] = { 1, 1, 1, 1, 1, 1, 0, 1, 0, 0, 1, 0, 0, 1, 1 };
246  /* minimum bands required for cloud processing */
247  int32_t cld_min_bnd[] = { 1, 1, 1, 1, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 1 };
248  /* The following emperically derived factors will correct the l2gen radiances
249  and reflectances to those that chimaera expects - probably the difference
250  between OBPG and EOSDIS calibration */
251  // *** I have temporarily removed the can change for a test
252  //float chim_rad_corr[] = { 0.965407, 0.973168, 1.00678, 1.00244, 0.963511,
253  float chim_rad_corr[] = { 1.0, 1.0, 1.0, 1.0, 1.0,
254  // WDR Jan 2021 try 5% low in 1st 5 bands
255  //float chim_rad_corr[] = { 0.5, 0.5, 0.5, 0.5, 0.5,
256  /* bands 645 859 1240 1640 2130 */
257  //-1., 0.999840, -1., 0.999979, 0.999794, 1.01814, 0.999760,
258  -1., 1.0, 1.0, 1.0, 1.0, 1.0, 1.0,
259  /* 930 approx 3750 1375 approx 8550 11000 412 12000 */
260  //-1., 0.986288, 0.994909 };
261  -1., 1.0, 1.0 };
262  /* 13600 approx 469 555 */
263 
264  /* Guard the transfer array creation to only 1 per run */
265  static int32_t firstcall = 0;
266  /*
267  * for the met data,
268  * set the merra profile heights in reverse order to match the order in the
269  * profiles used by chimaera
270  */
271  int32_t nlvl = 42, nlvl_cmp = 101, ilvl, is_land, cld_flg;
272  int32_t bad_rad, ice_flg, glint_flg;
273  int32_t npix_scan, lst, len, pst, pen, apx, aln, itot, nland;
274  unsigned char sfc_lvl, trop_lvl;
275  float merra_p_set[] = { 0.1, 0.3, 0.4, 0.5, 0.7, 1., 2., 3., 4., 5., 7., 10.,
276  20., 30., 40., 50., 70., 100., 150., 200., 250., 300., 350., 400.,
277  450., 500., 550., 600., 650., 700., 725., 750., 775., 800., 825.,
278  850., 875., 900., 925., 950., 975., 1000. };
279  float merra_t[nlvl], merra_p[nlvl], merra_q[nlvl], merra_h[nlvl];
280  double cmp_t[nlvl_cmp], cmp_mixr[nlvl_cmp], cmp_h[nlvl_cmp];
281  double cmp_p[nlvl_cmp], cmp_p_set[nlvl_cmp];
282  scnstr *meta;
283  /*
284  get the # pixels
285  and for now, make sure they match the # coming in
286  */
287  ctr_que = l1que.nq / 2; /* the center of the queue = our primary line */
288 
289  npix = l1rec->npix;
290  // WDR test nlin = 3;
291  nlin = 3;
292  dbg_print = 0;
293 
294  dim_ctl_.npix = npix;
295  dim_ctl_.nbnd_albedo = 6; /* the MODIS # 'albedo bands' */
296  nbnd_albedo = dim_ctl_.nbnd_albedo;
297  dim_ctl_.nlin = nlin;
298  dim_ctl_.nbnd = ncmp_bnd; /* a bnd # used from MODIS */
299  nbnd = ncmp_bnd;
300  dim_ctl_.nlvl_model = nlvl_cmp; /* the set # interpolated to for chimaera */
301  dim_ctl_.scan = l1que.r[ctr_que].iscan;
302  dim_ctl_.st_samp = 1; /* probably not used, but ftn 1-origin start samp */
303  meta = scene_meta_get();
304  /* get the time info down to the day - all that is used */
305  dim_ctl_.g_year = meta->start_year;
306  dim_ctl_.g_day = meta->start_day;
307 
308  /* Allocate arrays to pass to the f90 routine with all the information
309  together: all real arrays into a real array etc */
310  *nfloat = npix * nlin * nbnd + /* reflectance */
311  npix * nlin * nbnd_albedo + /* band uncertainty */
312  2 * nbnd_albedo + /* uncertainty info */
313  7 * npix * nlin + /* geom info */
314  4 * npix * nlin * nlvl_cmp + /* met profiles */
315  8 * npix * nlin + /* 2D anc data */
316  5 * npix * nlin; /* surface albedo for 5 bands */
317 
318  nbnd_ref = l1rec->l1file->nbands;
319  nbnd_emis = l1rec->l1file->nbandsir;
320  sensor_id = l1rec->l1file->sensorID;
321  if( firstcall == 0 )
322  {
323  firstcall = 1;
324  if( ( *tdat = (float *) malloc( *nfloat * sizeof(float) ) ) == NULL )
325  {
326  printf( "%s - %d: Allocation of real storage failed\n",
327  __FILE__, __LINE__ );
328  exit(3);
329  }
330  /*
331  * : all byte arrays
332  */
333  *nubyte = 2 * npix * nlin + /* for the ancillary byte stuff */
334  23 * npix * nlin + /* for the cloud mask stuff */
335  ncmp_bnd; /* for the band availability array */
336  if( ( *ubdat = (unsigned char *)
337  malloc( *nubyte * sizeof(unsigned char) ) ) == NULL )
338  {
339  printf( "%s - %d: Allocation of byte storage failed\n",
340  __FILE__, __LINE__ );
341  exit(3);
342  }
343  /*
344  * : all int32 arrays
345  */
346  *nint32 = npix * nlin;
347  if( ( *i32dat = (int32_t *) malloc( *nint32 * sizeof(int32_t) ) ) == NULL )
348  {
349  printf( "%s - %d: Allocation of i32 storage failed\n",
350  __FILE__, __LINE__ );
351  exit(3);
352  }
353  /*
354  * Set up the cloud band presence and L1 index here
355  */
356  for( ibnd = 0; ibnd < ncmp_bnd; ibnd++ )
357  cld_wav[ibnd] = ( sensor_id == OCIS ) ?
358  cld_wav_oci[ibnd] : cld_wav_mod[ibnd];
359 
360  for( ibnd = 0; ibnd < ncmp_bnd; ibnd++ )
361  {
362  ix_bnd = bindex_get( cld_wav[ibnd] );
363  if( ( ix_bnd < 0 ) && ( ref_for_cmb[ibnd] != 2 ) ) // if no matching,
364  // non-cirrus band was found
365  {
366  cmp_there[ibnd] = 0;
367  l1ix[ibnd] = -1;
368  }
369  else
370  {
371  cmp_there[ibnd] = 1;
372  if( ref_for_cmb[ibnd] == 0 ) // emissive
373  l1ix[ibnd] = ix_bnd;
374  else if( ref_for_cmb[ibnd] == 1 ) // reflective
375  l1ix[ibnd] = ix_bnd;
376  else //cirrus
377  l1ix[ibnd] = 0;
378  }
379  }
380  /*
381  * This code will optionally force the available bands down to the OCI bands
382  */
383  force_oci = 0;
384  printf( "OCI band forcing is set to %d\n", force_oci );
385  if( force_oci == 1 )
386  {
387  for( ibnd = 0; ibnd < ncmp_bnd; ibnd++ )
388  cmp_there[ibnd] *= oci_bnd_avail[ibnd];
389  }
390  /*
391  * If the minimum band set for 2.1 and 1.6 nm cloud products
392  * (cld_min_bnd) is not in this instrument (cmp_there), report it and
393  * stop processing here
394  */
395  printf( "Talley of current instrument's wavelengths\n" );
396  printf( "Cloud wave is wave is\n" );
397  printf( "wavelength available required\n" );
398  cld_missed = 0;
399  for( ibnd = 0; ibnd < ncmp_bnd; ibnd++ )
400  {
401  if( ( cld_min_bnd[ibnd] == 1 ) && ( cmp_there[ibnd] == 0 ) )
402  cld_missed = 1;
403  printf( "%10d %9d %8d\n", cld_wav[ibnd], cmp_there[ibnd],
404  cld_min_bnd[ibnd] );
405  }
406  if( cld_missed == 1 )
407  {
408  printf( "%s, %d: The required wavelengths for cloud processing were not found, Exiting\n", __FILE__, __LINE__ );
409  exit(FATAL_ERROR);
410  }
411  }
412 
413  F0 = l1rec->Fo;
414 
415  /* go through the chimaera refl (refl) rad (emiss) bands */
416  for( ibnd = 0; ibnd < ncmp_bnd; ibnd++ )
417  {
418  for( iln = 0; iln < nlin; iln++ )
419  {
420  qln = iln + ctr_que - nlin / 2;
421  for( ipx = 0; ipx < npix; ipx++ )
422  {
423  /* only write the center line value */
424  if( ( iln == 1) && ( dbg_print == 1 ) )
425  {
426  printf( "%s, %d: bnd %d, lin %d, pix %d, rad %f\n",
427  __FILE__, __LINE__, ibnd, iln, ipx,
428  (*tdat)[ ipx + npix * ( ibnd + ncmp_bnd * iln ) ] );
429  }
430  /* only substitute if the band exists (for now) */
431  if( cmp_there[ibnd] == 1 )
432  {
433  /* for the reflective */
434  if( ref_for_cmb[ibnd] == 1 )
435  {
436  rad = l1que.r[qln].Lt[ l1ix[ ibnd ] + nbnd_ref * ipx ];
437  solz = l1que.r[qln].solz[ipx ];
438  out = rad * PI / ( cos( solz * PI / 180. ) * F0[ l1ix[ ibnd ] ] );
439  (*tdat)[ ipx + npix * ( ibnd + ncmp_bnd * iln ) ] =
440  chim_rad_corr[ibnd] * out;
441  }
442  else if( ref_for_cmb[ibnd] == 2 ) /* for the cirrus */
443  {
444  solz = l1que.r[qln].solz[ipx ];
445  rad = l1que.r[qln].rho_cirrus[ipx];
446  (*tdat)[ ipx + npix * ( ibnd + ncmp_bnd * iln ) ] =
447  chim_rad_corr[ibnd] * rad * cos( solz * PI / 180. );
448  }
449  else /* for emissive */
450  {
451  (*tdat)[ ipx + npix * ( ibnd + ncmp_bnd * iln ) ] =
452  chim_rad_corr[ibnd] *
453  10. * l1que.r[qln].Ltir[ ( l1ix[ ibnd ] - nbnd_ref ) +
454  nbnd_emis * ipx ];
455  }
456  }
457  /* for the missing... try -999.0 */
458  else
459  {
460  (*tdat)[ ipx + npix * ( ibnd + ncmp_bnd * iln ) ] = -999.0;
461  }
462  /* repeat write of the center line value */
463  if( ( iln == 1 ) && (dbg_print == 1 ) )
464  {
465  printf( "%s, %d: bnd %d, lin %d, pix %d, rad %f\n",
466  __FILE__, __LINE__, ibnd, iln, ipx,
467  (*tdat)[ ipx + npix * ( ibnd + ncmp_bnd * iln ) ] );
468  }
469  }
470  }
471  }
472  /*
473  * the uncertainty with 6 band_albedo - I have a little on this:
474  * There is a equation in modis_science_module.f90 that shows how the
475  * info is used:
476  * refl_unc = spec_uncertain * exp(band_uncertainty) / uncertain_sf
477  * This is a kind of odd exponential relation.
478  * It also shows that I might be better using 1. for the dummy uncertain_sf
479  * value
480  *
481  * so 0 values are OK for now except the uncertain_sf (used in denominator)
482  *
483  * *** NOTE *** that the band_uncertainty in the chimaera code is
484  * actually a unsigned byte or i*1. Now, assigning the real data to that
485  * in the cloud code should work just fine - just some overkill in the
486  * value description. However, making this data a char array would be
487  * work for very little gain and could make problems if done wrong. It
488  * could also hide the problem we're looking for too. So, I'm leaving
489  * this as-is for now.
490  */
491  foff = npix * nlin * ncmp_bnd; /* offset to the output data */
492  for( ibnd = 0; ibnd < nbnd_albedo; ibnd++ )
493  {
494  for( iln = 0; iln < nlin; iln++ )
495  {
496  qln = iln + ctr_que - nlin / 2;
497  for( ipx = 0; ipx < npix; ipx++ )
498  {
499  /* only write the center line value */
500  if( ( iln == 1 ) && (dbg_print == 1 ) )
501  {
502  printf( "%s, %d: bnd %d, lin %d, pix %d, UNC %f\n",
503  __FILE__, __LINE__, ibnd, iln, ipx,
504  (*tdat)[ foff + ipx + npix * ( ibnd + nbnd_albedo * iln ) ] );
505  }
506  /* substitute a 0 for all */
507  (*tdat)[ foff + ipx + npix * ( ibnd + nbnd_albedo * iln ) ] = 0.;
508 
509  /* repeat write of the center line value */
510  if( ( iln == 1 ) && (dbg_print == 1 ) )
511  {
512  printf( "%s, %d: bnd %d, lin %d, pix %d, UNC %f\n",
513  __FILE__, __LINE__, ibnd, iln, ipx,
514  (*tdat)[ foff + ipx + npix * ( ibnd + nbnd_albedo * iln ) ] );
515  }
516  }
517  }
518  }
519  /*
520  * also the nbnd_albedo long arrays of spec_uncertain and uncertain_sf see
521  * above
522  */
523  foff += npix * nlin * nbnd_albedo;
524  foff2 = foff + nbnd_albedo;
525  for( ibnd = 0; ibnd < nbnd_albedo; ibnd++ )
526  {
527  (*tdat)[ foff + ibnd ] = 0.;
528  (*tdat)[ foff2 + ibnd ] = 1.;
529  }
530  /*
531  * transfer the geolocation and view angle information over
532  */
533  foff = foff2 + nbnd_albedo;
534  foff2 = npix * nlin;
535  /* lat and lon at the l1rec values */
536  for( iln = 0; iln < nlin; iln++ )
537  {
538  qln = iln + ctr_que - nlin / 2;
539  for( ipx = 0; ipx < npix; ipx++ )
540  {
541  if( ( iln == 1 ) && ( dbg_print == 1 ) )
542  {
543  printf( "%s, %d: lin %d, pix %d, INITIAL lon %f, lat %f, senz %f, sena %f, solz %f, sola %f, relaz %f\n",
544  __FILE__, __LINE__, iln, ipx,
545  (*tdat)[ foff + ipx + npix * iln ], (*tdat)[ foff + foff2 + ipx + npix * iln ],
546  (*tdat)[ foff + 2 * foff2 + ipx + npix * iln ],
547  (*tdat)[ foff + 3 * foff2 + ipx + npix * iln ],
548  (*tdat)[ foff + 4 * foff2 + ipx + npix * iln ],
549  (*tdat)[ foff + 5 * foff2 + ipx + npix * iln ],
550  (*tdat)[ foff + 6 * foff2 + ipx + npix * iln ] );
551  }
552  /* lat and lon */
553  out = l1que.r[qln].lat[ipx];
554  (*tdat)[ foff + ipx + npix * iln ] = out;
555  out = l1que.r[qln].lon[ipx];
556  (*tdat)[ foff + foff2 + ipx + npix * iln ] = out;
557  /* senz, sena, sola, solz, relaz */
558  out = l1que.r[qln].senz[ipx];
559  (*tdat)[ foff + 2 * foff2 + ipx + npix * iln ] = out;
560  out = l1que.r[qln].sena[ipx];
561  (*tdat)[ foff + 3 * foff2 + ipx + npix * iln ] = out;
562  out = l1que.r[qln].sola[ipx];
563  (*tdat)[ foff + 4 * foff2 + ipx + npix * iln ] = out;
564  out = l1que.r[qln].solz[ipx];
565  (*tdat)[ foff + 5 * foff2 + ipx + npix * iln ] = out;
566  out = l1que.r[qln].delphi[ipx];
567  (*tdat)[ foff + 6 * foff2 + ipx + npix * iln ] = -out; /* their relaz is (-) ours */
568 
569  if( ( iln == 1 ) && ( dbg_print == 1 ) )
570  {
571  printf( "%s, %d: lin %d, pix %d, FINAL lon %f, lat %f, senz %f, sena %f, solz %f, sola %f, relaz %f\n",
572  __FILE__, __LINE__, iln, ipx,
573  (*tdat)[ foff + ipx + npix * iln ], (*tdat)[ foff + foff2 + ipx + npix * iln ],
574  (*tdat)[ foff + 2 * foff2 + ipx + npix * iln ],
575  (*tdat)[ foff + 3 * foff2 + ipx + npix * iln ],
576  (*tdat)[ foff + 4 * foff2 + ipx + npix * iln ],
577  (*tdat)[ foff + 5 * foff2 + ipx + npix * iln ],
578  (*tdat)[ foff + 6 * foff2 + ipx + npix * iln ] );
579  }
580  }
581  }
582  /*
583  * next is the met info
584  */
585  foff += 7 * foff2; /* start of the profiles */
586  /* set up the clean hi res profile */
587  make_profile_101_( cmp_p_set );
588 
589  uoff = 0;
590  for( iln = 0; iln < nlin; iln++ )
591  {
592  qln = iln + ctr_que - nlin / 2;
593  for( ipx = 0; ipx < npix; ipx++ )
594  {
595  memcpy( merra_p, merra_p_set, nlvl * sizeof(float) );
596  for( ilvl = 0; ilvl < nlvl; ilvl++ )
597  {
598  /* note that the profiles for chimaera are reverse of the MERRA,
599  so in making the merra arrays from the l1rec stuff, we reverse it */
600  merra_t[ nlvl - 1 - ilvl ] = l1que.r[qln].anc_add->prof_temp[ ilvl + nlvl * ipx ];
601  merra_q[ nlvl - 1 - ilvl ] = l1que.r[qln].anc_add->prof_q[ ilvl + nlvl * ipx ];
602  merra_h[ nlvl - 1 - ilvl ] = l1que.r[qln].anc_add->prof_height[ ilvl + nlvl * ipx ];
603  }
604 /* WDR trad test point tpix = 2, tlin = 1; */
605 int tpix = 2, tlin = 1;
606 if( (ipx == tpix) && ( iln == tlin ) && ( dbg_print == 1 ) )
607  {
608  printf( "\n\n%s, %d: merra_p for pix: %d, lin: %d\n", __FILE__, __LINE__, ipx, iln );
609  for( ilvl = 0; ilvl < nlvl; ilvl++ )
610  printf( "%f ", merra_p[ilvl] );
611  printf( "\n" );
612 
613  printf( "%s, %d: merra_t for pix: %d, lin: %d\n", __FILE__, __LINE__, ipx, iln );
614  for( ilvl = 0; ilvl < nlvl; ilvl++ )
615  printf( "%f ", merra_t[ilvl] );
616  printf( "\n" );
617 
618  printf( "%s, %d: merra_q for pix: %d, lin: %d\n", __FILE__, __LINE__, ipx, iln );
619  for( ilvl = 0; ilvl < nlvl; ilvl++ )
620  printf( "%f ", merra_q[ilvl] );
621  printf( "\n" );
622 
623  printf( "%s, %d: merra_h for pix: %d, lin: %d\n", __FILE__, __LINE__, ipx, iln );
624  for( ilvl = 0; ilvl < nlvl; ilvl++ )
625  printf( "%f ", merra_h[ilvl] );
626  printf( "\n" );
627  }
628 
629  /*
630  * for this profile, make the 101 level chimaera profile
631  * and put the chimaera profiles into the storage
632  */
633  memcpy( cmp_p, cmp_p_set, nlvl_cmp * sizeof( double) );
634 /* WDR **** test branch to get around interpolation of merra */
635 /* ilvl = -899; WDR use a pre-computed fixed profile */
636 ilvl = 0; /* WDR use the real profiles */
637 if( ilvl == -899 )
638  {
639  mk_cmp_prof_dum( merra_p, merra_t, merra_q, merra_h, l1que.r[qln].sfcp[ipx],
640  l1que.r[qln].sfct[ipx], l1que.r[qln].sfcrh[ipx],
641  l1que.r[qln].lat[ipx], &sfc_lvl, &trop_lvl, cmp_p, cmp_t,
642  cmp_mixr, cmp_h );
643  }
644 else
645  {
646  mk_cmp_prof( merra_p, merra_t, merra_q, merra_h, l1que.r[qln].sfcp[ipx],
647  l1que.r[qln].sfct[ipx], l1que.r[qln].sfcrh[ipx],
648  l1que.r[qln].lat[ipx], &sfc_lvl, &trop_lvl, cmp_p, cmp_t,
649  cmp_mixr, cmp_h );
650  }
651  /* as sfc_lvl, trop_lvl go to ftn, make them 1-origin */
652  sfc_lvl = ( sfc_lvl == nlvl_cmp ) ? sfc_lvl : sfc_lvl + 1;
653  trop_lvl = ( trop_lvl == nlvl_cmp ) ? trop_lvl : trop_lvl + 1;
654 
655  /*
656  * WDR Look through the profiles and see if all is OK with them.
657  * Note the problems
658  */
659  for( ilvl = 0; ilvl < nlvl_cmp; ilvl++ )
660  {
661  if( ( cmp_t[ilvl] > 350. ) || ( cmp_t[ilvl] < 100. ) )
662  {
663  printf( "PROFILE ODD T: %f, iln: %d, ipx: %d, ilvl: %d\n",
664  cmp_t[ilvl], iln, ipx, ilvl );
665  }
666  if( ( cmp_mixr[ilvl] > 100. ) || ( cmp_mixr[ilvl] < 0 ) )
667  {
668  printf( "PROFILE ODD MIXR: %f, iln: %d, ipx: %d, ilvl: %d\n",
669  cmp_mixr[ilvl], iln, ipx, ilvl );
670  }
671  if( ( cmp_h[ilvl] > 1000000. ) || ( cmp_h[ilvl] < -20000. ) )
672  {
673  printf( "PROFILE ODD height: %f, iln: %d, ipx: %d, ilvl: %d\n",
674  cmp_h[ilvl], iln, ipx, ilvl );
675  }
676  if( ( cmp_p[ilvl] > 1200. ) || ( cmp_p[ilvl] < 0. ) )
677  {
678  printf( "PROFILE ODD P: %f, iln: %d, ipx: %d, ilvl: %d\n",
679  cmp_p[ilvl], iln, ipx, ilvl );
680  }
681  }
682 /* the tdat at foff starts with mixr
683  it runs all pixels fastest, then lines, themn levels
684  so t is at foff + npix * nlin * nlvl_cmp
685  p is at foff + 2 * nlin * nlvl_cmp
686  h is at foff + 3 * nlin * nlvl_cmp
687 
688  the offset for pix, lin level is the base above plus
689  ipx * npix * ( iln + nlin * ilvl )
690 */
691 /* I need to print the profiles before they get re-done and then again after
692  they are updated. Maybe a routine for that would be usefull */
693 if( ( ipx == tpix ) && ( iln == tlin ) && ( dbg_print == 1 ) )
694  {
695  printf( "/n%s, %d: mix, t, p, h profiles BEFORE, pix %d, lin %d\n", __FILE__, __LINE__, ipx, iln );
696  profile_print( (*tdat) + foff, (*ubdat), (*i32dat), ipx, iln, npix, nlin );
697  printf( "OUR sfcp: %f, sfct: %f\n", l1que.r[qln].sfcp[ipx], l1que.r[qln].sfct[ipx] );
698  printf( "mk_cmp_prof sfc_lvl: %d, trop_lvl: %d\n", sfc_lvl, trop_lvl );
699  }
700  for( ilvl = 0; ilvl < nlvl_cmp; ilvl++ )
701  {
702  (*tdat)[foff + ipx + npix * ( iln + nlin * ilvl ) ] = cmp_mixr[ilvl];
703  foff2 = foff + npix * nlin * nlvl_cmp;
704  (*tdat)[foff2 + ipx + npix * ( iln + nlin * ilvl ) ] = cmp_t[ilvl];
705  foff2 = foff + 2 * npix * nlin * nlvl_cmp;
706  (*tdat)[foff2 + ipx + npix * ( iln + nlin * ilvl ) ] = cmp_p[ilvl];
707  foff2 = foff + 3 * npix * nlin * nlvl_cmp;
708  (*tdat)[foff2 + ipx + npix * ( iln + nlin * ilvl ) ] = cmp_h[ilvl];
709  }
710  /*
711  * add the single-level met parameters
712  * sfc T
713  */
714  foff2 = foff + 4 * npix * nlin * nlvl_cmp;
715  (*tdat)[foff2 + ipx + npix * iln ] = 273.15 + l1que.r[qln].sfct[ipx];
716  /* sfc P */
717  foff2 += npix * nlin;
718  (*tdat)[foff2 + ipx + npix * iln ] = l1que.r[qln].sfcp[ipx];
719  /* wind speed */
720  foff2 += npix * nlin;
721  (*tdat)[foff2 + ipx + npix * iln ] = l1que.r[qln].ws[ipx];
722  /* O3 */
723  foff2 += npix * nlin;
724  (*tdat)[foff2 + ipx + npix * iln ] = 1.e3 * l1que.r[qln].oz[ipx];
725  /* ice frac and snow frac */
726  is_land = l1que.r[qln].land[ipx];
727 /*
728 if( ( ipx == 2 ) && ( iln == 1 ) )
729 printf( "flag: %d\n", l1que.r[qln].flags[ipx]);
730 */
731  foff2 += npix * nlin;
732  (*tdat)[foff2 + ipx + npix * iln ] = ( is_land ) ? 0. :
733  l1que.r[qln].icefr[ipx];
734 
735  foff2 += npix * nlin;
736  (*tdat)[foff2 + ipx + npix * iln ] = ( is_land ) ?
737  l1que.r[qln].icefr[ipx] : 0;
738  /* alt o3 - originally an alt o3 source but... */
739  foff2 += npix * nlin;
740  (*tdat)[foff2 + ipx + npix * iln ] = 1.e3 * l1que.r[qln].oz[ipx];
741  /* alt ice conc */
742  foff2 += npix * nlin;
743  /* WDR to globalize this value
744  (*tdat)[foff2 + ipx + npix * iln ] = ( is_land ) ? 0. :
745  l1que.r[qln].icefr[ipx];
746  */
747  (*tdat)[foff2 + ipx + npix * iln ] = l1que.r[qln].icefr[ipx];
748  /* We will get the surface albedo from l2gen now */
749  foff2 += npix * nlin;
750  (*tdat)[foff2 + ipx + npix * iln ] =
751  l1que.r[qln].cld_dat->sfc_albedo_659[ipx];
752  foff2 += npix * nlin;
753  (*tdat)[foff2 + ipx + npix * iln ] =
754  l1que.r[qln].cld_dat->sfc_albedo_858[ipx];
755  foff2 += npix * nlin;
756  (*tdat)[foff2 + ipx + npix * iln ] =
757  l1que.r[qln].cld_dat->sfc_albedo_1240[ipx];
758  foff2 += npix * nlin;
759  (*tdat)[foff2 + ipx + npix * iln ] =
760  l1que.r[qln].cld_dat->sfc_albedo_1640[ipx];
761  foff2 += npix * nlin;
762  (*tdat)[foff2 + ipx + npix * iln ] =
763  l1que.r[qln].cld_dat->sfc_albedo_2130[ipx];
764 
765  /* sfc_lvl and trop_lvl gotten with the profile above */
766  /* note that this is unsigned char data now */
767  /* also note that the ftn expects 1-origin levels so add 1 */
768  (*ubdat)[ uoff + ipx + npix * iln ] = sfc_lvl;
769  uoff2 = uoff + npix * nlin;
770  (*ubdat)[ uoff2 + ipx + npix * iln ] = trop_lvl;
771 
772  /* the I32 met info is the next */
773  /* just try inserting the ice fraction as percent */
774  (*i32dat)[ ipx + npix * iln ] = 100 * l1que.r[qln].icefr[ipx];
775 
776  /* the remaining byte data is all from the cloud mask that is
777  a MODIS product. We have one thing: the cloud mask
778  and we'll see how that does... */
779  /* some set-up and CLD_DET */
780  uoff2 += npix * nlin;
781  bad_rad = ( l1que.r[qln].Lt[l1ix[0]+nbnd_ref * ipx] == BAD_INT ) ? 1 : 0;
782  cld_flg = l1que.r[qln].cloud[ipx];
783  ice_flg = l1que.r[qln].ice[ipx];
784  glint_flg = l1que.r[qln].glint[ipx];
785  npix_scan = l1que.r[qln].npix;
786  (*ubdat)[ uoff2 + ipx + npix * iln ] = ( bad_rad == 0 ) ? 1 : 0;
787  // We will use the cloud mask file categories if the file was specified
788  if( l1_input->cld_msk_file[0]) {
789  char cld_category;
790  get_sdps_cld_mask( &(l1que.r[qln]), ipx, &cld_category );
791  /* CONF_CLD, CLR_66, CLR_95, CLR_99 */
792  uoff2 += npix * nlin;
793  (*ubdat)[ uoff2 + ipx + npix * iln ] = ( cld_category == 0 ) ? 1 : 0;
794  uoff2 += npix * nlin;
795  (*ubdat)[ uoff2 + ipx + npix * iln ] = ( cld_category == 1 ) ? 1 : 0;
796  uoff2 += npix * nlin;
797  (*ubdat)[ uoff2 + ipx + npix * iln ] = ( cld_category == 2 ) ? 1 : 0;
798  uoff2 += npix * nlin;
799  (*ubdat)[ uoff2 + ipx + npix * iln ] = ( cld_category >= 3 ) ? 1 : 0;
800  } else {
801  // use the binary cloud flag
802  /* CONF_CLD, CLR_66, CLR_95, CLR_99 */
803  uoff2 += npix * nlin;
804  (*ubdat)[ uoff2 + ipx + npix * iln ] = ( cld_flg != 0 ) ? 1 : 0;
805  uoff2 += npix * nlin;
806  (*ubdat)[ uoff2 + ipx + npix * iln ] = ( cld_flg != 0 ) ? 1 : 0;
807  uoff2 += npix * nlin;
808  (*ubdat)[ uoff2 + ipx + npix * iln ] = ( cld_flg != 0 ) ? 1 : 0;
809  uoff2 += npix * nlin;
810  (*ubdat)[ uoff2 + ipx + npix * iln ] = 0;
811  }
812  /* SNO_SFC */
813  uoff2 += npix * nlin;
814  (*ubdat)[ uoff2 + ipx + npix * iln ] =
815  ( ( is_land == 1 ) && ( ice_flg == 1 ) ) ? 1 : 0;
816  /* WTR_SFC */
817  uoff2 += npix * nlin;
818  (*ubdat)[ uoff2 + ipx + npix * iln ] = ( is_land == 0 ) ? 1 : 0;
819  /* COAST_SFC */
820  uoff2 += npix * nlin;
821  lst = ( iln < 1 ) ? iln : iln - 1;
822  len = ( iln >= ( nlin - 1 ) ) ? iln : iln + 1;
823  pst = ( ipx <= 0 ) ? 0 : ipx -1;
824  pen = ( ipx >= ( npix_scan - 1 ) ) ? ipx : ipx + 1;
825  (*ubdat)[ uoff2 + ipx + npix * iln ] = 0;
826  itot = 0;
827  nland = 0;
828  for( aln = lst; aln <= len; aln++ )
829  for( apx = pst; apx <= pen; apx++ )
830  {
831  itot++;
832  if( l1que.r[aln].land[apx] ) nland++;
833  }
834  if( ( nland != 0 ) && ( nland != itot ) )
835  (*ubdat)[ uoff2 + ipx + npix * iln ] = 1;
836  /* DESERT_SFC */
837  uoff2 += npix * nlin;
838  (*ubdat)[ uoff2 + ipx + npix * iln ] = 0;
839  /* LND_SFC */
840  uoff2 += npix * nlin;
841  (*ubdat)[ uoff2 + ipx + npix * iln ] = ( is_land ) ? 1 : 0;
842  /* NIGHT - solz > 90 */
843  uoff2 += npix * nlin;
844  (*ubdat)[ uoff2 + ipx + npix * iln ] =
845  ( l1que.r[iln].solz[ipx] > 90. ) ? 1 : 0;
846  /* GLINT */
847  uoff2 += npix * nlin;
848  (*ubdat)[ uoff2 + ipx + npix * iln ] =
849  ( glint_flg ) ? 1 : 0;
850  /* OCEAN_NO_SNOW */
851  uoff2 += npix * nlin;
852  (*ubdat)[ uoff2 + ipx + npix * iln ] =
853  ( ( is_land == 0 ) && ( ice_flg == 0 ) ) ? 1 : 0;
854  /* OCEAN_SNOW */
855  uoff2 += npix * nlin;
856  (*ubdat)[ uoff2 + ipx + npix * iln ] =
857  ( ( is_land == 0 ) && ( ice_flg == 1 ) ) ? 1 : 0;
858  /* LND_NO_SNOW */
859  uoff2 += npix * nlin;
860  (*ubdat)[ uoff2 + ipx + npix * iln ] =
861  ( ( is_land == 1 ) && ( ice_flg == 0 ) ) ? 1 : 0;
862  /* LND_SNOW */
863  uoff2 += npix * nlin;
864  (*ubdat)[ uoff2 + ipx + npix * iln ] =
865  ( ( is_land == 1 ) && ( ice_flg == 1 ) ) ? 1 : 0;
866  /* TST_H_138 */
867  uoff2 += npix * nlin;
868  (*ubdat)[ uoff2 + ipx + npix * iln ] = 0;
869  /* TST_VIS_REFL */
870  uoff2 += npix * nlin;
871  (*ubdat)[ uoff2 + ipx + npix * iln ] = 0;
872  /* TST_VIS_RATIO */
873  uoff2 += npix * nlin;
874  (*ubdat)[ uoff2 + ipx + npix * iln ] = 0;
875  /* VIS_CLD_250 */
876  uoff2 += npix * nlin;
877  (*ubdat)[ uoff2 + ipx + npix * iln ] = 0;
878  /* APPL_HCLD_138 */
879  uoff2 += npix * nlin;
880  (*ubdat)[ uoff2 + ipx + npix * iln ] = 0;
881  /* APPL_VIS_REFL */
882  uoff2 += npix * nlin;
883  (*ubdat)[ uoff2 + ipx + npix * iln ] = 0;
884  /* APPL_VIS_NIR_RATIO */
885  uoff2 += npix * nlin;
886  (*ubdat)[ uoff2 + ipx + npix * iln ] = 0;
887  /* end all inputs */
888 
889 if( ( ipx == tpix ) && ( iln == tlin ) && ( dbg_print == 1 ) )
890  {
891  printf( "/n%s, %d: mix, t, p, h profiles AFTER, pix %d, lin %d\n", __FILE__, __LINE__, ipx, iln );
892  profile_print( (*tdat) + foff , (*ubdat), (*i32dat), ipx, iln, npix, nlin );
893  }
894  /*
895  * note that we also get the trop_lvl, sfc_lvl which go into another
896  * storage area further on in the work
897  */
898  }
899  }
900  /*
901  * add the cloud band presence array to the end of the byte array
902  */
903  memcpy( ( *ubdat + 25 * npix * nlin ), cmp_there, ncmp_bnd );
904 
905  return(0);
906  }
907 
908 int profile_print( float *prof, unsigned char *ubdat, int32_t *i32dat,
909  int32_t ipx, int32_t iln, int32_t npix, int32_t nlin )
910  /*******************************************************************
911 
912  profile_print
913 
914  purpose: print the met profile and 2d data at a point
915 
916  Returns type: int - 0 if good
917 
918  Parameters: (in calling order)
919  Type Name I/O Description
920  ---- ---- --- -----------
921  float * prof I pointer to the start of the
922  met data
923  unsigned char * ubdat I unsigned char data
924  int32_t ipx I pixel to look at
925  int32_t iln I line to look at
926  int32_t npix I # pixels
927  int32_t nlin I # lines
928  Modification history:
929  Programmer Date Description of change
930  ---------- ---- ---------------------
931  W. Robinson 28-Jan-2019 Original development
932 
933 *******************************************************************/
934  {
935  int nlvl_cmp = 101;
936  int32_t off, ilvl;
937  /* just print each profile */
938  printf( "mixr profile\n" );
939  for( ilvl = 0; ilvl < nlvl_cmp; ilvl++ )
940  {
941  printf( "%f ", prof[ ipx + npix * ( iln + nlin * ilvl ) ] );
942  }
943  printf( "\nT profile\n" );
944  off = npix * nlin * nlvl_cmp;
945  for( ilvl = 0; ilvl < nlvl_cmp; ilvl++ )
946  {
947  printf( "%f ", prof[ off + ipx + npix * ( iln + nlin * ilvl ) ] );
948  }
949  printf( "\nPRESS profile\n" );
950  off += npix * nlin * nlvl_cmp;
951  for( ilvl = 0; ilvl < nlvl_cmp; ilvl++ )
952  {
953  printf( "%f ", prof[ off + ipx + npix * ( iln + nlin * ilvl ) ] );
954  }
955  printf( "\nHEIGHT profile\n" );
956  off += npix * nlin * nlvl_cmp;
957  for( ilvl = 0; ilvl < nlvl_cmp; ilvl++ )
958  {
959  printf( "%f ", prof[ off + ipx + npix * ( iln + nlin * ilvl ) ] );
960  }
961  printf( "\n" );
962  /* on to the single-level params */
963  off += npix * nlin * nlvl_cmp;
964  printf( "TSFC: %f, ", prof[ off + ipx + npix * iln] );
965  off += npix * nlin;
966  printf( "PSFC: %f, ", prof[ off + ipx + npix * iln] );
967  off += npix * nlin;
968  printf( "WIND SP: %f, ", prof[ off + ipx + npix * iln] );
969  off += npix * nlin;
970  printf( "O3: %f\n", prof[ off + ipx + npix * iln] );
971 
972  off += npix * nlin;
973  printf( "ICE FR: %f, ", prof[ off + ipx + npix * iln] );
974  off += npix * nlin;
975  printf( "SNO FR: %f, ", prof[ off + ipx + npix * iln] );
976  off += npix * nlin;
977  printf( "ALT O3: %f, ", prof[ off + ipx + npix * iln] );
978  off += npix * nlin;
979  printf( "ALT ICEC: %f\n", prof[ off + ipx + npix * iln] );
980  /* the first 2 met byte quantities - the 101 level profile surface
981  and tropopause levels */
982  off = 0;
983  printf( "SFC_LVL: %d, ", ubdat[ off + ipx + npix * iln ] );
984  off += npix * nlin;
985  printf( "TROP_LVL: %d\n", ubdat[ off + ipx + npix * iln ] );
986  /* the 'alternate snow/ice type (from NSIDC) */
987  printf( "ALT ICE: %d\n", i32dat[ ipx + npix * iln ] );
988  /* the remaining byte values are the cloud mask stuff */
989  off = 2 * npix * nlin;
990  printf( "---- Cloud Mask values ----\n" );
991  printf( "CLD_DET: %d, ", ubdat[ off + ipx + npix * iln ] );
992  off += npix * nlin;
993  printf( "CONF_CLD: %d, ", ubdat[ off + ipx + npix * iln ] );
994  off += npix * nlin;
995  printf( "CLR_66: %d, ", ubdat[ off + ipx + npix * iln ] );
996  off += npix * nlin;
997  printf( "CLR_95: %d\n", ubdat[ off + ipx + npix * iln ] );
998  off += npix * nlin;
999  printf( "CLR_99: %d, ", ubdat[ off + ipx + npix * iln ] );
1000  off += npix * nlin;
1001  printf( "SNO_SFC: %d, ", ubdat[ off + ipx + npix * iln ] );
1002  off += npix * nlin;
1003  printf( "WTR_SFC: %d, ", ubdat[ off + ipx + npix * iln ] );
1004  off += npix * nlin;
1005  printf( "COAST_SFC: %d\n", ubdat[ off + ipx + npix * iln ] );
1006  off += npix * nlin;
1007  printf( "DESERT_SFC: %d, ", ubdat[ off + ipx + npix * iln ] );
1008  off += npix * nlin;
1009  printf( "LND_SFC: %d, ", ubdat[ off + ipx + npix * iln ] );
1010  off += npix * nlin;
1011  printf( "NIGHT: %d, ", ubdat[ off + ipx + npix * iln ] );
1012  off += npix * nlin;
1013  printf( "GLINT: %d\n", ubdat[ off + ipx + npix * iln ] );
1014  off += npix * nlin;
1015  printf( "OCEAN_NO_SNOW: %d, ", ubdat[ off + ipx + npix * iln ] );
1016  off += npix * nlin;
1017  printf( "OCEAN_SNOW: %d, ", ubdat[ off + ipx + npix * iln ] );
1018  off += npix * nlin;
1019  printf( "LND_NO_SNOW: %d, ", ubdat[ off + ipx + npix * iln ] );
1020  off += npix * nlin;
1021  printf( "LND_SNOW: %d\n", ubdat[ off + ipx + npix * iln ] );
1022  off += npix * nlin;
1023  printf( "TST_H_138: %d, ", ubdat[ off + ipx + npix * iln ] );
1024  off += npix * nlin;
1025  printf( "TST_VIS_REFL: %d, ", ubdat[ off + ipx + npix * iln ] );
1026  off += npix * nlin;
1027  printf( "TST_VIS_RATIO: %d, ", ubdat[ off + ipx + npix * iln ] );
1028  off += npix * nlin;
1029  printf( "VIS_CLD_250: %d\n", ubdat[ off + ipx + npix * iln ] );
1030  off += npix * nlin;
1031  printf( "APPL_HCLD_138: %d, ", ubdat[ off + ipx + npix * iln ] );
1032  off += npix * nlin;
1033  printf( "APPL_VIS_REFL: %d, ", ubdat[ off + ipx + npix * iln ] );
1034  off += npix * nlin;
1035  printf( "APPL_VIS_NIR_RATIO: %d\n", ubdat[ off + ipx + npix * iln ] );
1036  off += npix * nlin;
1037  /* end? */
1038  return 0;
1039  }
1040 /* WDR **** test end-around to mk_cmp_prof */
1041 int mk_cmp_prof_dum( float *merra_p, float *merra_t, float *merra_q,
1042  float *merra_h, float sfcp, float sfct, float sfcrh, float lat,
1043  unsigned char *sfc_lvl, unsigned char *trop_lvl, double *cmp_p,
1044  double *cmp_t, double *cmp_mixr, double *cmp_h )
1045  {
1046 int i;
1047 double cmp_t_sav[] = {169.25176566420146, 197.35942572651811, 229.18349451149692, 256.22238210609601, 236.47864107966123, 244.04297143175555, 250.64605396062848, 255.49783596464286, 259.17682096634508, 260.50430632229126, 257.86788008325004, 255.09753268656993, 251.71866532458688, 246.82264824496451, 241.36301970269031, 235.5349625222656, 231.00564672010188, 230.31934481415178, 230.00717490122784, 230.93984650147675, 231.87556038742846, 230.052070835427, 226.94875351064999, 223.97554681909486, 221.12246382681033, 218.38062746953614, 216.05483908715939, 214.30433557126059, 212.6156777870857, 210.98488863951465, 209.57034993410883, 208.26534656680437, 207.00140487891071, 205.76477951859837, 204.56229701519121, 202.84595260841155, 200.1528837094385, 197.5345872033561, 194.98734605240188, 193.13906753041528, 192.9482175288388, 192.76222219178675, 192.58086243374066, 192.4039337826197, 193.53690804615815, 196.34328186967463, 199.08486131023724, 201.76426680177968, 204.38396142841776, 206.94626326403974, 209.4240557622999, 211.67158053966773, 213.87221009140157, 216.02762928535265, 218.13943261959307, 220.23999924343335, 222.60373354556071, 224.92166874653532, 227.195309078017, 229.42608466977327, 232.27719286025973, 235.2490670940424, 238.1670467211311, 241.03276062011722, 243.91780941249539, 246.75240714620259, 249.53800835678237, 251.86502860055904, 253.8587763082154, 255.81919333430849, 257.63971457966039, 259.29891772708743, 260.9312384604865, 262.72494342240276, 264.64753610551918, 266.53988144929855, 268.11359331445857, 269.60080666913444, 271.01286592906087, 272.25331134687139, 273.4751007120372, 274.88788770642338, 276.32402654921054, 277.67617255366838, 278.94743905007527, 280.29684643297759, 281.87085668556011, 283.47072360439103, 285.24727818913414, 286.9975584364218, 288.51282458375113, 289.86087429979796, 290.9986136887851, 292.01521247752953, 292.98262145756013, 294.3041990659554, 296.79569609374886, 298.98862037321277, 299.76233992810609, 300.50664057118684, 301.24118800223761};
1048 double cmp_mixr_sav[] = {0.0030000000000000001, 0.0030000000000000001, 0.0030000000000000001, 0.0030000000000000001, 0.0039293894442529974, 0.0041105013907719468, 0.0042181900744832808, 0.0042143496342834938, 0.0041817655664085482, 0.0040206101090032517, 0.0038733849643674614, 0.0037377625227534746, 0.0036014648248259636, 0.0034516475997961819, 0.0033167026788735537, 0.0031947714963073749, 0.0030799596646610928, 0.0030107622372746654, 0.0029488582454394335, 0.0028982059410255015, 0.0028502657213637195, 0.0027944201318237261, 0.002735964452701974, 0.0026799596042977963, 0.0026262174675935851, 0.0025745708296473057, 0.0025405554258138494, 0.0025323804296621087, 0.0025244942581909551, 0.0025168783380373483, 0.0025258323028017112, 0.0025409217199495382, 0.0025555363514953174, 0.0025643709192777427, 0.0025716416839911219, 0.0025546327064356832, 0.0024931393172969081, 0.002433353276920958, 0.0023751897106692147, 0.0023510380165387293, 0.0024102799348228623, 0.0024680149123855986, 0.0025243109557570816, 0.0025792315352972882, 0.0028074932565275365, 0.0032578001900602956, 0.0036977103048750353, 0.004127644072243016, 0.004547996715297346, 0.0049591401890269129, 0.0066045793017774166, 0.015756209535939904, 0.024716888476006896, 0.033493476685974542, 0.042092466755785318, 0.053504463790107065, 0.094126872282568774, 0.13396219155187214, 0.17303627285925954, 0.21137369397371381, 0.2419968812989492, 0.27022626866094007, 0.2979437192418275, 0.32516470551490928, 0.47386770138225009, 0.6199703171142984, 0.76354752329508391, 1.0340410272474989, 1.3924930017834096, 1.7449525187114237, 1.9710464191297217, 2.0459308727278538, 2.1196020481996749, 2.5849697692954705, 3.3725913913975889, 4.1478216949005233, 4.7278626505249006, 5.2595586368380491, 5.6780053593354278, 5.7887852404941018, 5.897899014248777, 6.0126629733222074, 6.1272686176990323, 6.2612715902934664, 6.4138250668383652, 6.5300489624532512, 6.6239450570569449, 7.0237148492647679, 7.815759173341303, 8.9338062006928265, 10.017175527482264, 10.798574208009653, 11.482688439271284, 12.855657707404751, 14.06097496976534, 15.451677990360071, 8.9087798522868766, 0.078892832367705168, 0.0013115547243546515, 0.0021613451297737749, 0.0030000000000000001};
1049 double cmp_h_sav[] = {80980.567272357701, 75343.876190403083, 70225.982411112418, 65480.628319062816, 61428.924238065607, 58024.80202191414, 54950.191567802227, 52150.37234583289, 49587.069685576469, 47234.584895480606, 45084.856633888245, 43122.927977172032, 41324.952076504, 39676.318479632821, 38164.924587601548, 36777.388481093178, 35497.403939587413, 34300.298902152295, 33167.424793334678, 32088.91680780418, 31057.094888806638, 30073.813431125316, 29143.272510847557, 28263.483356793786, 27430.050001579777, 26639.098949354469, 25886.659507298184, 25168.400851046954, 24481.003799506794, 23822.279970437601, 23190.014293749664, 22582.119678830768, 21996.942353189086, 21433.083441024752, 20889.269993475449, 20365.028820377422, 19861.183794284312, 19377.767922145697, 18913.565376345625, 18466.731479797825, 18033.779798131261, 17612.242600176087, 17201.593473696255, 16801.341547642598, 16409.703419308389, 16023.364531449324, 15640.568137969527, 15261.317752839021, 14885.61129854926, 14513.441856962587, 14144.824125415456, 13779.920194073944, 13418.849581909997, 13061.570770637654, 12708.041363820343, 12358.193358432209, 12011.718940291992, 11668.35429065583, 11328.08453068694, 10990.892967344218, 10656.282389846725, 10323.666245846885, 9992.9598216377744, 9664.201332244118, 9337.3653911268993, 9012.4264031402581, 8689.4162094312233, 8368.613449980001, 8050.4524006411266, 7735.0947019042451, 7422.5961680835417, 7113.1000037295735, 6806.6644285353668, 6503.107856676912, 6202.1379607025819, 5903.6184955729223, 5607.7124190540144, 5314.6091843005188, 5024.3518657619488, 4737.0487534217273, 4452.7644388850267, 4171.3480686550502, 3892.6336221371671, 3616.5978083090913, 3343.2676087364471, 3072.5944718766254, 2804.3890955354977, 2538.46734163782, 2274.6417716957349, 2012.7539832113782, 1752.8699864080911, 1495.1635489650282, 1239.7954748266484, 986.82637292768879, 736.25029352497961, 487.89682088402327, 241.65371459693083, 0, -243.21093547707787, -481.72170087446557, 0};
1050 *sfc_lvl = 97;
1051 *trop_lvl = 44;
1052 for( i = 0; i < 101; i++ )
1053  {
1054  *(cmp_t + i) = *(cmp_t_sav + i);
1055  *(cmp_mixr + i) = *(cmp_mixr_sav + i);
1056  *(cmp_h + i) = *(cmp_h_sav + i);
1057  }
1058  return 0;
1059  }
1060 
1061 int mk_cmp_prof( float *merra_p, float *merra_t, float *merra_q,
1062  float *merra_h, float sfcp, float sfct, float sfcrh, float lat,
1063  unsigned char *sfc_lvl, unsigned char *trop_lvl, double *cmp_p,
1064  double *cmp_t, double *cmp_mixr, double *cmp_h )
1065  {
1066  unsigned char get_trop( double *, double *, unsigned char );
1067  int height_profile_( double *, double *, double *, double *, int *,
1068  double * );
1069  int profile_to_101_( double *, double *, double *, int *, double *,
1070  double *, double *, double *, int * );
1071  int32_t nlvl = 42, nlvl_cmp = 101, ioz = 0, ilvl, kstart;
1072  int32_t nlvl_d = nlvl + 1;
1073  float oval, a_factor;
1074  double p_init[nlvl_d], lcl_p[nlvl_d], lcl_t[nlvl_d];
1075  double lcl_w[nlvl_d], lcl_h[nlvl_d], lat_d, sfcp_d;
1076  /*
1077  * Some l1 conventions that need to be addressed:
1078  * the p, q, mixr, h arrays need a extra bottom level at 1100 mb (beyond
1079  * normal seen p) and need to be double.
1080  * the merra_q needs to be converted to mixr via:
1081  * w = q ( 1 - q )^-1 q = spec hum, w = mixing ratio
1082  * and the merra_t needs 273.15 added to it to get deg K
1083  * and the sfc RH needs to be made into a mixing ratio
1084  * lastly, for levels with (-) t, ppropagate higher level to it
1085  */
1086  lat_d = lat;
1087  sfcp_d = sfcp;
1088 
1089  for( ilvl = 0; ilvl < nlvl; ilvl++ )
1090  {
1091  merra_q[ilvl] = 1000. * merra_q[ilvl] / ( 1. - merra_q[ilvl]);
1092  merra_t[ilvl] += 273.15;
1093  }
1094  sfct += 273.15;
1095  /* use cvt_rh_to_q */
1096  met_cvt_rh_to_q( 1, &sfcp, MET_UNITS__P_HPA, &sfct, MET_UNITS__T_K,
1097  &sfcrh, &oval, MET_UNITS__Q_G_KG );
1098 /* WDR test to see that the conversion worked
1099 float ex_val;
1100 met_cvt_q_to_rh(1, &sfcp, MET_UNITS__P_HPA, &sfct, MET_UNITS__T_K,
1101  &oval, MET_UNITS__Q_KG_KG, &ex_val );
1102  END TEST */
1103  sfcrh = oval / ( 1. - oval ); /* now, this is the mixing ratio */
1104 
1105  /* transfer the 42 level profile info to the local double 43 level arrays */
1106  for( ilvl = 0; ilvl < nlvl; ilvl++ )
1107  {
1108  lcl_p[ilvl] = merra_p[ilvl];
1109  lcl_t[ilvl] = merra_t[ilvl];
1110  lcl_w[ilvl] = merra_q[ilvl];
1111  lcl_h[ilvl] = merra_h[ilvl];
1112 
1113  if( lcl_t[ilvl] < 0. )
1114  {
1115  lcl_t[ilvl] = lcl_t[ ilvl - 1 ];
1116  lcl_w[ilvl] = lcl_w[ ilvl - 1 ];
1117  lcl_h[ilvl] = lcl_h[ ilvl - 1 ];
1118  }
1119  }
1120  lcl_p[nlvl] = 1100.;
1121  lcl_t[nlvl] = lcl_t[ nlvl - 1 ];
1122  lcl_w[nlvl] = lcl_w[ nlvl - 1 ];
1123  lcl_h[nlvl] = lcl_h[ nlvl - 1 ];
1124 
1125 /* we will just duplicate the method used in ancillary_module.f90
1126  to set up the incoming profile and placing the surface values
1127  and then interpolation even though I'd probably do it differently
1128 */
1129  memcpy( p_init, lcl_p, nlvl_d * sizeof(double) );
1130 
1131  /* first, if sfc p is > next lowest p level, set the p level as the last */
1132  if( ( sfcp > 0 ) && ( lcl_p[ nlvl_d - 2 ] > sfcp ) )
1133  *sfc_lvl = nlvl_d - 1;
1134  else
1135  *sfc_lvl = 0;
1136 
1137  /* look through the lower half of the levels and find the sfc_lvl for
1138  the rest */
1139  kstart = nlvl_d / 2;
1140 
1141  for( ilvl = kstart; ilvl < nlvl_d; ilvl++ )
1142  {
1143  if( ( sfcp > 0 ) && ( lcl_p[ilvl] > sfcp ) )
1144  {
1145  if( *sfc_lvl == 0 )
1146  {
1147  *sfc_lvl = ilvl;
1148  lcl_t[ilvl] = sfct;
1149  /* now this next part is ver-batum from chimaera code but I don't
1150  understand the reason they did it this way */
1151  if( ( sfcp - lcl_p[ ilvl - 1 ] < 5. ) ||
1152  ( lcl_p[ilvl] - sfcp < 5. ) )
1153  {
1154  lcl_p[ilvl] = ( lcl_p[ilvl] + lcl_p[ ilvl - 1 ] ) / 2.;
1155  }
1156  else
1157  {
1158  lcl_p[ilvl] = sfcp;
1159  }
1160  lcl_w[ilvl] = sfcrh;
1161  }
1162  else
1163  {
1164  lcl_t[ilvl] = sfct;
1165  lcl_w[ilvl] = sfcrh;
1166  lcl_p[ilvl] = p_init[ ilvl - 1 ];
1167  }
1168  }
1169  }
1170  /* more dubvious mods: add the surface level into the coarse profile */
1171  if( *sfc_lvl != nlvl_d )
1172  merra_p[ nlvl_d - 1 ] = p_init[ ilvl - 1 ];
1173  else
1174  lcl_p[ nlvl - 1 ] = sfcp;
1175  lcl_t[ nlvl - 1 ] = sfct;
1176  lcl_w[ nlvl - 1 ] = sfcrh;
1177 
1178  /* on to getting the lowest level of the 101 level profile */
1179  kstart = nlvl_cmp / 2;
1180  for( ilvl = kstart; ilvl < nlvl_cmp; ilvl++ )
1181  {
1182  if( cmp_p[ilvl] >= sfcp )
1183  {
1184  *sfc_lvl = ilvl;
1185  break;
1186  }
1187  }
1188 
1189  profile_to_101_( lcl_p, lcl_t, lcl_w, &nlvl, &lat_d, cmp_p, cmp_t,
1190  cmp_mixr, &ioz );
1191 
1192  /* instead of assigning the sfct, sfcrh (now mixr) to the sfc_lvl, it
1193  interpolates in p coordinates the resulting T, mixr */
1194  a_factor = ( sfcp - cmp_p[ *sfc_lvl - 1 ] ) /
1195  ( cmp_p[*sfc_lvl] - cmp_p[ *sfc_lvl - 1 ] );
1196  cmp_t[*sfc_lvl] = cmp_t[ *sfc_lvl - 1 ] + a_factor *
1197  ( cmp_t[*sfc_lvl] - cmp_t[ *sfc_lvl - 1 ] );
1198  cmp_mixr[*sfc_lvl] = cmp_mixr[ *sfc_lvl - 1 ] + a_factor *
1199  ( cmp_mixr[*sfc_lvl] - cmp_mixr[ *sfc_lvl - 1 ] );
1200 
1201  cmp_p[*sfc_lvl] = sfcp;
1202 
1203  /* and then follow with the height profile */
1204  height_profile_( cmp_p, cmp_t, cmp_mixr, cmp_h, &nlvl_cmp, &sfcp_d );
1205  cmp_h[nlvl_cmp - 1 ] = 0.;
1206 
1207  /* also find the tropopause level - call a chimaera-based algorithm */
1208  *trop_lvl = get_trop( cmp_t, cmp_p, *sfc_lvl );
1209 
1210  return 0;
1211  }
1212 
1213 unsigned char get_trop( double *cmp_t, double *cmp_p, unsigned char sfc_lvl )
1214  {
1215  unsigned char trop_lvl;
1216  int32_t ilev, imin;
1217  float xmin, ptop = 100.;
1218 
1219  xmin = 999999.;
1220  imin = 1;
1221 
1222  for( ilev = 0; ilev < sfc_lvl - 5; ilev++ )
1223  {
1224  if( ( cmp_t[ilev] < xmin ) && ( cmp_p[ilev] > ptop ) )
1225  {
1226  xmin = cmp_t[ilev];
1227  imin = ilev;
1228  }
1229  }
1230 
1231  /* don't allow trop height > 400 mb (level 71) */
1232  trop_lvl = 200;
1233  for( ilev = imin; ilev < 71; ilev++ )
1234  {
1235  if( ( cmp_t[ ilev - 1 ] >= cmp_t[ilev] ) &&
1236  ( cmp_t[ ilev + 1 ] > cmp_t[ilev] ) )
1237  {
1238  trop_lvl = ilev;
1239  break;
1240  }
1241  }
1242 
1243  if( trop_lvl == 200 ) trop_lvl = imin;
1244 
1245  return trop_lvl;
1246  }
1247 
1248 int ncio_grab_ub_ds(int ncid, char *ds_name, unsigned char *data)
1249 /*******************************************************************
1250 
1251  ncio_grab_ub_ds
1252 
1253  purpose: grab dataset and return it in unsigned char format
1254 
1255  Returns type: int - 0 if OK, -1 if problem
1256 
1257  Parameters: (in calling order)
1258  Type Name I/O Description
1259  ---- ---- --- -----------
1260  int ncid I netcdf id of file
1261  char * ds_name I name of dataset to read
1262  unsigned char * data O pointer to a pre-allocated
1263  array to receive the data
1264 
1265  Modification history:
1266  Programmer Date Description of change
1267  ---------- ---- ---------------------
1268  W. Robinson 26 Nov 2018 original development
1269 
1270  *******************************************************************/ {
1271  int status;
1272  int var_id;
1273  /*
1274  * get ID of the dataset
1275  */
1276  if ((status = nc_inq_varid(ncid, ds_name, &var_id)) != NC_NOERR) {
1277  printf("%s, %d: nc_inq_varid returned error %d\n", __FILE__, __LINE__,
1278  status);
1279  return -1;
1280  }
1281  /*
1282  * read the dataset as a unsigned char
1283  */
1284  if ((status = nc_get_var_uchar(ncid, var_id, data)) != NC_NOERR) {
1285  printf("%s, %d: nc_get_var_uchar returned error %d\n",
1286  __FILE__, __LINE__, status);
1287  return -1;
1288  }
1289  return 0;
1290 }
1291 
1292 int ncio_grab_i32_ds(int ncid, char *ds_name, int32_t *data)
1293 /*******************************************************************
1294 
1295  ncio_grab_i32_ds
1296 
1297  purpose: grab dataset and return it in nteger format
1298 
1299  Returns type: int - 0 if OK, -1 if problem
1300 
1301  Parameters: (in calling order)
1302  Type Name I/O Description
1303  ---- ---- --- -----------
1304  int ncid I netcdf id of file
1305  char * ds_name I name of dataset to read
1306  int32_t * data O pointer to a pre-allocated
1307  array to receive the data
1308 
1309  Modification history:
1310  Programmer Date Description of change
1311  ---------- ---- ---------------------
1312  W. Robinson 26 Nov 2018 original development
1313 
1314  *******************************************************************/ {
1315  int status;
1316  int var_id;
1317  /*
1318  * get ID of the dataset
1319  */
1320  if ((status = nc_inq_varid(ncid, ds_name, &var_id)) != NC_NOERR) {
1321  printf("%s, %d: nc_inq_varid returned error %d\n", __FILE__, __LINE__,
1322  status);
1323  return -1;
1324  }
1325  /*
1326  * read the dataset as a unsigned char
1327  */
1328  if ((status = nc_get_var_int(ncid, var_id, (int32_t *)data)) != NC_NOERR) {
1329  printf("%s, %d: nc_get_var_int returned error %d\n",
1330  __FILE__, __LINE__, status);
1331  return -1;
1332  }
1333  return 0;
1334 }
#define MET_UNITS__Q_G_KG
Definition: met_cvt.h:29
struct @125 dim_ctl_
#define MET_UNITS__T_K
Definition: met_cvt.h:26
int status
Definition: l1_czcs_hdf.c:32
#define CAT_CER_1600
Definition: l2prod.h:402
#define CAT_CER_1621
Definition: l2prod.h:405
#define NULL
Definition: decode_rs.h:63
map< string, float > F0
Definition: DDSensor.cpp:39
no change in intended resolving MODur00064 Corrected handling of bad ephemeris attitude resolving resolving GSFcd00179 Corrected handling of fill values for[Sensor|Solar][Zenith|Azimuth] resolving MODxl01751 Changed to validate LUT version against a value retrieved from the resolving MODxl02056 Changed to calculate Solar Diffuser angles without adjustment for estimated post launch changes in the MODIS orientation relative to incidentally resolving defects MODxl01766 Also resolves MODxl01947 Changed to ignore fill values in SCI_ABNORM and SCI_STATE rather than treating them as resolving MODxl01780 Changed to use spacecraft ancillary data to recognise when the mirror encoder data is being set by side A or side B and to change calculations accordingly This removes the need for seperate LUTs for Side A and Side B data it makes the new LUTs incompatible with older versions of the and vice versa Also resolves MODxl01685 A more robust GRing algorithm is being which will create a non default GRing anytime there s even a single geolocated pixel in a granule Removed obsolete messages from seed as required for compatibility with version of the SDP toolkit Corrected test output file names to end in out
Definition: HISTORY.txt:422
read l1rec
unsigned char * get_cmp_byt(l2str *l2rec, int prodnum)
Definition: get_cmp.c:118
@ PRODWARN
#define CAT_CER_2100
Definition: l2prod.h:401
float * lat
int make_profile_101_(double *p)
int g_year
Definition: get_cmp.c:34
#define CAT_COT_2100
Definition: l2prod.h:403
int nlin
Definition: get_cmp.c:28
#define CAT_COT_1621
Definition: l2prod.h:406
int st_samp
Definition: get_cmp.c:33
int nbnd
Definition: get_cmp.c:29
instr * input
#define PI
Definition: l3_get_org.c:6
l1qstr l1que
Definition: getl1rec.c:7
int bindex_get(int32_t wave)
Definition: windex.c:45
void ch_cld_sci_(float *, int *, unsigned char *, int *, int32_t *, int *, int *, char *)
int ncio_grab_i32_ds(int ncid, char *ds_name, int32_t *data)
Definition: get_cmp.c:1292
int get_cmp(l2str *l2rec, int prodnum, float prod[])
Definition: get_cmp.c:40
int mk_cmp_prof(float *merra_p, float *merra_t, float *merra_q, float *merra_h, float sfcp, float sfct, float sfcrh, float lat, unsigned char *sfc_lvl, unsigned char *trop_lvl, double *cmp_p, double *cmp_t, double *cmp_mixr, double *cmp_h)
Definition: get_cmp.c:1061
int scan
Definition: get_cmp.c:32
int g_day
Definition: get_cmp.c:35
int nlvl_model
Definition: get_cmp.c:31
l1_input_t * l1_input
Definition: l1_options.c:9
#define OCIS
Definition: sensorDefs.h:43
#define FATAL_ERROR
Definition: swl0_parms.h:5
int get_sdps_cld_mask(l1str *l1rec, int32_t ip, char *cld_category)
Definition: cloud_flag.c:5
int set_cmp(l2str *l2rec, float **tdat, int32_t *nfloat, int32_t **i32dat, int32_t *nint32, unsigned char **ubdat, int32_t *nubyte)
Definition: get_cmp.c:198
unsigned char get_trop(double *cmp_t, double *cmp_p, unsigned char sfc_lvl)
Definition: get_cmp.c:1213
no change in intended resolving MODur00064 Corrected handling of bad ephemeris attitude data
Definition: HISTORY.txt:356
int ncio_grab_ub_ds(int ncid, char *ds_name, unsigned char *data)
Definition: get_cmp.c:1248
int profile_to_101_(double *p, double *t, double *w, int *nn, double *nlat, double *pp, double *tt, double *ww, int *is_o3)
#define CAT_COT_1600
Definition: l2prod.h:404
int profile_print(float *prof, unsigned char *ubdat, int32_t *i32dat, int32_t ipx, int32_t iln, int32_t npix, int32_t nlin)
Definition: get_cmp.c:908
scnstr * scene_meta_get(void)
Definition: scene_meta.c:237
#define BAD_INT
Definition: genutils.h:23
int mk_cmp_prof_dum(float *merra_p, float *merra_t, float *merra_q, float *merra_h, float sfcp, float sfct, float sfcrh, float lat, unsigned char *sfc_lvl, unsigned char *trop_lvl, double *cmp_p, double *cmp_t, double *cmp_mixr, double *cmp_h)
Definition: get_cmp.c:1041
int height_profile_(double *p, double *t, double *w, double *z, int *nn, double *np0)
#define MET_UNITS__P_HPA
Definition: met_cvt.h:25
int nbnd_albedo
Definition: get_cmp.c:30
int met_cvt_rh_to_q(int nval, float *pres, int p_type, float *temp, int t_type, float *rh, float *q, int q_type)
Definition: met_cvt.c:99
@ PRODFAIL
int i
Definition: decode_rs.h:71
int compute_cmp(l2str *l2rec)
Definition: get_cmp.c:167
int npix
Definition: get_cmp.c:27