ocssw
V2022
|
val_extract.c
Go to the documentation of this file.
78 { "boxsizekm", BOX_SIZE_KM_KEY, "N", OPTION_DBL, "grab all pixels within N kilometers (positive integer)" },
88 { "boxsizekm", BOX_SIZE_KM_KEY, "N", OPTION_DBL, "grab all pixels within N kilometers (positive integer)" },
99 { "l2qc", L2QC_KEY, "FLAG=decimal ...", 0, "Max percentages (in decimal form) an extract can contain "
101 { "valid_ranges", RANGES_KEY, "var_prefix=min:max ...", 0, "Valid ranges for variables. Any values "
103 { "ignore_flags", IGNORE_KEY, "FLAG ...", 0, "Ignore values for ALL variables in pixels containing "
106 { "count_flags", COUNT_KEY, "FLAG ...", 0, "Count the number of pixels containing ANY of the flag(s) "
112 { 0, 0, 0, OPTION_DOC, "The flag names for the L2QC thresholds and to ignore them will be matched exactly "
113 "and this will error if that flag is not found. valid_ranges uses case-sensitive prefix matching. "
116 { 0, 0, 0, OPTION_DOC, "Failing the L2QC will successfully process the file, but will not process any "
120 { 0, 0, 0, OPTION_DOC, "The \"center pixel\" for lat-/lon-based regions is only guaranteed to be inside the "
121 "actual data, but isn't necessarily the actual center due to weirdly shaped granules and endless edge "
122 "cases involving partial polygonal collision. Line- and pixel-based should be more accurate, but "
156 if (arguments->start_line == VALEXTRACT_UNSET && arguments->start_pixel == VALEXTRACT_UNSET && arguments->start_lat == VALEXTRACT_UNSET && arguments->start_lon == VALEXTRACT_UNSET) {
157 olog_crit(arguments->log, "sline and spixl or slat and slon are required if boxsize is provided\n");
159 } else if (arguments->start_lat != VALEXTRACT_UNSET && arguments->start_lon != VALEXTRACT_UNSET) {
161 if (arguments->start_lat < -90 || arguments->start_lat > 90 || arguments->start_lon < -180 || arguments->start_lon > 180) {
177 } else if (arguments->start_lat != VALEXTRACT_UNSET || arguments->end_lat != VALEXTRACT_UNSET || arguments->start_lon != VALEXTRACT_UNSET || arguments->end_lon != VALEXTRACT_UNSET) {
178 if (arguments->start_lat < -90 || arguments->start_lat > 90 || arguments->start_lon < -180 || arguments->start_lon > 180) {
181 } else if (arguments->end_lat < -90 || arguments->end_lat > 90 || arguments->end_lon < -180 || arguments->end_lon > 180) {
194 } else if (arguments->start_line != VALEXTRACT_UNSET || arguments->end_line != VALEXTRACT_UNSET || arguments->start_pixel != VALEXTRACT_UNSET || arguments->end_pixel != VALEXTRACT_UNSET) {
195 if (arguments->start_line < 0 || arguments->end_line < 0 || arguments->start_pixel < 0 || arguments->end_pixel < 0) {
196 olog_crit(arguments->log, "sline, eline, spixl, and epixl are all required and must be positive integers\n");
288 olog_crit(arguments->log, "Error allocating memory in '%s', near line %d\n", __FILE__, __LINE__);
293 olog_crit(arguments->log, "Error allocating memory in '%s', near line %d\n", __FILE__, __LINE__);
309 olog_crit(arguments->log, "Error allocating memory in '%s', near line %d\n", __FILE__, __LINE__);
348 olog_crit(arguments->log, "Error allocating memory in '%s', near line %d\n", __FILE__, __LINE__);
364 olog_crit(arguments->log, "Error allocating memory in '%s', near line %d\n", __FILE__, __LINE__);
406 olog_crit(arguments->log, "Error allocating memory in '%s', near line %d\n", __FILE__, __LINE__);
416 olog_crit(arguments->log, "Error allocating memory in '%s', near line %d\n", __FILE__, __LINE__);
446 olog_crit(arguments->log, "Error allocating memory in '%s', near line %d\n", __FILE__, __LINE__);
456 olog_crit(arguments->log, "Error allocating memory in '%s', near line %d\n", __FILE__, __LINE__);
486 olog_crit(arguments->log, "Error allocating memory in '%s', near line %d\n", __FILE__, __LINE__);
496 olog_crit(arguments->log, "Error allocating memory in '%s', near line %d\n", __FILE__, __LINE__);
532 static double process_scan_line_att(val_extract_arguments *arguments, nc_region *region, const char *name);
533 static double process_location_var(val_extract_arguments *arguments, nc_region *region, const char *name);
534 static int process_df_var_attrs(val_extract_arguments *arguments, shash *attributes, int ncid, int varid, bool prepend_path);
539 static void get_array_ranges(const double *sorted_data, int length, double start, double end, int *start_i, int *end_i);
633 if ((strcmp(dim_name, "number_of_lines") == 0) || (strcmp(dim_name, "Number_of_Scan_Lines") == 0)) {
636 } else if ((strcmp(dim_name, "pixels_per_line") == 0) || (strcmp(dim_name, "Pixels_per_Scan_Line") == 0)) {
639 } else if ((strcmp(dim_name, "pixel_control_points") == 0) || (strcmp(dim_name, "Number_of_Pixel_Control_Points") == 0)) {
659 .line_dimid = line_dimid, .pixel_dimid = pixel_dimid, .pixel_control_dimid = pixel_control_dimid,
671 if (arguments->start_lat == -90. && arguments->end_lat == 90. && arguments->start_lon == -180. && arguments->end_lon == 180.) {
675 olog_crit(arguments->log, "Error allocating memory in '%s', near line %d\n", __FILE__, __LINE__);
708 int geo_box_margin = arguments->box_size >> 1; // if odd, -1, then divide by 2; else divide by 2
757 olog_notice(arguments->log, "epixl %d >= pixel count (%d); adjusting\n", end_pixel, pixel_count);
764 olog_crit(arguments->log, "Error allocating memory in '%s', near line %d\n", __FILE__, __LINE__);
813 // olog_debug(arguments->log, "%s, gid = %d, varid = %d, nc_ret = %d\n", arguments->products[i], gid, varid, nc_ret);
907 static uint32_t find_closest_index(double target_lat, double target_lon, uint32_t length, double *lats, double *lons) {
922 const long double pi = 3.14159265358979323846264338327950288419716939937510582097494459230781640628620899L;
936 static uint32_t find_closest_index_polar(double target_lat, double target_lon, uint32_t length, double *lats, double *lons) {
958 static nc_box *add_to_boxes(nc_box *boxes, unsigned *box_shift, int *box_i, int *box_max, int line_i, int start_pixel, int end_pixel) {
967 nc_box new_box = { .start = { line_i, start_pixel }, .count = { 1, end_pixel - start_pixel + 1 } };
973 static bool polygon_contains(const double *poly_x, const double *poly_y, const int poly_n, const double x, const double y) {
976 if (((poly_x[i] > x) != (poly_x[j] > x)) && (y < (poly_y[j] - poly_y[i]) * (x - poly_x[i]) / (poly_x[j] - poly_x[i]) + poly_y[i])) {
984 static void polygon_center(double *poly_x, double *poly_y, const int poly_n, double *x, double *y) {
1013 // DBSCAN is a relatively simple algorithm to detect clusters of points. It's no longer used here due to requiring a density
1014 // factor that would either need a look up table or a bunch of extra analysis to find it first. The oddities documented
1023 static void dbscan_expand(struct dbscan *db, struct dbscan *p, const int cluster, const double epsilon, const int min_points) {
1040 static void dbscan(struct dbscan *db, const int db_count, const double epsilon, const int min_points) {
1061 // OPTICS is an algorithm to identify clusters of points in 2D space. The advantage of it is that it's
1062 // insensitive of cluster density, which is why it was chosen (pixel resolution = density). The reason
1063 // it's needed at all is because of gaps in data, such as when the SeaWiFS sensor switches tilt. When
1067 // Epsilon (eps, in Wikipedia's pseudo-code) isn't even used. I don't even use a getNeighbors function.
1068 // I already know the neighbors because it's just a grid, so each point just has all of its gridly
1069 // neighbors in its neighbor list. This is slightly incorrect because I'm using this to detect gaps and the
1070 // appropriate epsilon would simply discard them as neighbors. This entire bit is used specifically because
1071 // I can't (easily) know the appropriate epsilon; one might be able to use sensor lookup tables and geospatial
1072 // geometry to calculate the correct grid size and, therefore, epsilon. To keep this library as generic as
1073 // possible, I use OPTICS's density-independent concept and a maximum ratio to determine if a pixel is too
1074 // far away from the core and should be considered a new cluster. If a reachability-distance is X times
1075 // larger than the current cluster's moving average, it's a new cluster. For these reasons, and any
1076 // assumptions I've made for this specific application, the struct for the data point is a kind of weird
1077 // format (for convenience), so this algorithm isn't in a nice, generic library like it should be (nor do I
1087 static double optics_core_distance(const struct optic *db, const struct optic *p, const int min_points) {
1106 static void optics_update(struct optic *db, struct optic *p, const int min_points, pqueue *seeds) {
1122 static void optics(struct optic *db, const int db_count, const int min_points, struct optic **out_db) {
1152 // This assumes the latitude and longitude variables do not have any scaling or offset and that the
1153 // fill value is -999. The fill value is currently listed incorrectly in the data files, so it's a
1154 // moot point to do it correctly here. I only check the latitude array for -999; if one is -999,
1156 // Due to pre-screening for NAVFAILed pixels, as mentioned above, NAVFAIL will never actually be reported.
1159 size_t latlon_length = file->dim_lengths[file->line_dimid] * file->dim_lengths[file->pixel_dimid];
1162 olog_crit(arguments->log, "Error allocating memory in '%s', near line %d\n", __FILE__, __LINE__);
1167 olog_crit(arguments->log, "Error allocating memory in '%s', near line %d\n", __FILE__, __LINE__);
1177 if (!found_lat && (nc_ret = nc_inq_varid(file->gids[gid_i], "latitude", &varid)) == NC_NOERR) {
1181 if (!found_lon && (nc_ret = nc_inq_varid(file->gids[gid_i], "longitude", &varid)) == NC_NOERR) {
1195 const int dims[2] = { file->dim_lengths[file->line_dimid], file->dim_lengths[file->pixel_dimid] };
1199 // olog_debug(arguments->log, "Closest pixel: (%zd, %zd)\n", region->center.line, region->center.pixel);
1204 unflatten_index(closest_index = find_closest_index(arguments->start_lat, arguments->start_lon, latlon_length, lats, lons), 2, dims, result);
1209 distance_to_closest = sqrt(pow(lats[closest_index] - arguments->start_lat, 2) + pow(lons[closest_index] - arguments->start_lon, 2));
1213 closest_index = region->center.line * file->dim_lengths[file->pixel_dimid] + region->center.pixel;
1219 // olog_debug(arguments->log, "Closest pixel: %d (%zd, %zd), %f degrees away\n", closest_index, region->center.line, region->center.pixel, distance_to_closest);
1259 if ((int) grid_lats[i][j] != -999 && copysign(1, grid_lons[i][j]) != copysign(1, lons[closest_index])) {
1260 if (fabs(grid_lons[i][j] - lons[closest_index]) > fabs(grid_lons[i][j] + dateline_offset - lons[closest_index])) {
1327 if (current_count && current_total > 1e-10 && (out_db[db_i]->reachability / (current_total / current_count)) > arguments->optics_threshold) {
1329 olog_debug(arguments->log, "\tcount %d, total %f, threshold %f > %f\n", current_count, current_total, (out_db[db_i]->reachability / (current_total / current_count)), arguments->optics_threshold);
1330 olog_debug(arguments->log, "\t(%f / (%f/%d)) > %f\n", out_db[db_i]->reachability, current_total, current_count, arguments->optics_threshold);
1332 // Using the actual reachability would desensitize the detection because it would start off with too large of a total.
1333 // Using the previous average assumes that clusters have similar density. Assuming anything isn't ideal, but this
1346 olog_debug(arguments->log, "\tcount %d, total %f, threshold %f <= %f\n", current_count, current_total, (current_total / current_count), arguments->optics_threshold);
1347 olog_debug(arguments->log, "\t(%f/%d) <= %f\n", current_total, current_count, arguments->optics_threshold);
1361 if ((int) grid_lats[n_i][n_j] != -999 && (i != n_i || j != n_j) && grid_cluster[n_i][n_j] == cluster) {
1362 double neighbor_distance = sqrt(pow(grid_lats[i][j] - grid_lats[n_i][n_j], 2) + pow(grid_lons[i][j] - grid_lons[n_i][n_j], 2));
1373 olog_crit(arguments->log, "Point not found in file, %f degrees (distance to closest pixel) > %f (farthest neighbor)\n", distance_to_closest, max_neighbor_distance);
1386 // olog_debug(arguments->log, "Point found in file, %f degrees (distance to closest pixel) <= %f (farthest neighbor)\n", distance_to_closest, max_neighbor_distance);
1392 olog_crit(arguments->log, "Error allocating memory in '%s', near line %d\n", __FILE__, __LINE__);
1414 nc_box *new_box_ptr = add_to_boxes(boxes, &box_shift, &box_i, &box_max, i + line_start, this_start_pixel + pixel_start, j + pixel_start - 1);
1416 olog_crit(arguments->log, "Error allocating memory in '%s', near line %d\n", __FILE__, __LINE__);
1451 olog_crit(arguments->log, "Error allocating memory in '%s', near line %d\n", __FILE__, __LINE__);
1468 const double distance = vincenty_distance(arguments_lat, arguments_lon, lats[latlon_i], lons[latlon_i]);
1469 // printf("vincenty_distance(%f, %f, %f, %f) = %f\n", arguments_lat, arguments_lon, lats[latlon_i], lons[latlon_i], distance);
1477 nc_box *new_box_ptr = add_to_boxes(boxes, &box_shift, &box_i, &box_max, line_i, start_pixel, end_pixel);
1479 olog_crit(arguments->log, "Error allocating memory in '%s', near line %d\n", __FILE__, __LINE__);
1490 nc_box *new_box_ptr = add_to_boxes(boxes, &box_shift, &box_i, &box_max, line_i, start_pixel, end_pixel);
1492 olog_crit(arguments->log, "Error allocating memory in '%s', near line %d\n", __FILE__, __LINE__);
1519 olog_crit(arguments->log, "Error allocating memory in '%s', near line %d\n", __FILE__, __LINE__);
1545 if ((int) lats[latlon_i] != -999 && polygon_contains(poly_lats, poly_lons, 5, lats[latlon_i], lons[latlon_i])) {
1552 nc_box *new_box_ptr = add_to_boxes(boxes, &box_shift, &box_i, &box_max, line_i, start_pixel, end_pixel);
1554 olog_crit(arguments->log, "Error allocating memory in '%s', near line %d\n", __FILE__, __LINE__);
1565 nc_box *new_box_ptr = add_to_boxes(boxes, &box_shift, &box_i, &box_max, line_i, start_pixel, end_pixel);
1567 olog_crit(arguments->log, "Error allocating memory in '%s', near line %d\n", __FILE__, __LINE__);
1632 olog_crit(arguments->log, "Error allocating memory in '%s', near line %d\n", __FILE__, __LINE__);
1659 olog_crit(arguments->log, "Error getting dimension count for %s, error %d\n", var->name, nc_ret);
1666 olog_crit(arguments->log, "Error allocating memory in '%s', near line %d\n", __FILE__, __LINE__);
1681 var->is_geospatial = (var->ndims == 2 && var->dim_ids[0] == var->file->line_dimid && (var->dim_ids[1] == var->file->pixel_dimid || var->dim_ids[1] == var->file->pixel_control_dimid));
1682 var->uses_control_points = (var->ndims == 2 && var->dim_ids[1] == var->file->pixel_control_dimid);
1684 if ((nc_ret = nc_get_att_double(var->gid, var->varid, "scale_factor", &var->scale)) != NC_NOERR) {
1693 if ((nc_ret = nc_get_att_double(var->gid, var->varid, "add_offset", &var->offset)) != NC_NOERR) {
1694 if ((nc_ret = nc_get_att_double(var->gid, var->varid, "intercept", &var->offset)) != NC_NOERR) {
1702 if ((nc_ret = nc_get_att_double(var->gid, var->varid, "_FillValue", &var->fill)) != NC_NOERR) {
1703 if ((nc_ret = nc_get_att_double(var->gid, var->varid, "bad_value_scaled", &var->fill)) != NC_NOERR) {
1792 // olog_debug(arguments->log, "Center pixel coords: %zd, %zd\n", region->center.line, region->center.pixel);
1794 if ((nc_ret = nc_get_var1_double(var->gid, var->varid, center_point, ¢er_value)) != NC_NOERR) {
1821 if ((nc_ret = nc_get_varrd_double(var->gid, var->varid, region, 0, sorted_data)) != NC_NOERR) {
1826 } else if (var->dim_ids[0] == file->pixel_dimid || var->dim_ids[0] == file->pixel_control_dimid) {
1835 if ((nc_ret = nc_get_varrd_double(var->gid, var->varid, region, 1, sorted_data)) != NC_NOERR) {
1948 get_array_ranges(sorted_data, good_pixels, filter_start, filter_end, &filter_start_i, &filter_end_i);
1981 static void get_array_ranges(const double *sorted_data, const int length, const double start, const double end, int *start_i, int *end_i) {
2066 100000000000, 1000000000000, 10000000000000, 100000000000000, 1000000000000000, 10000000000000000,
2180 static int process_df_var_attrs(val_extract_arguments *arguments, shash *attributes, int ncid, int varid, bool prepend_path) {
2206 olog_crit(arguments->log, "Error getting attribute name %s/<%d>: %d\n", attname_full, i, nc_ret);
2210 olog_crit(arguments->log, "Error getting attribute value %s/%s: %d\n", attname_full, attname, nc_ret);
2259 if ((nc_ret = nc_inq_att(flags_gid, flags_varid, "flag_masks", &att_xtype, &u_flag_count)) != NC_NOERR) {
2273 if ((nc_ret = nc_inq_att(flags_gid, flags_varid, att_name, &att_xtype, &attr_length)) != NC_NOERR) {
2279 if ((nc_ret = nc_get_att_text(flags_gid, flags_varid, att_name, flag_meanings[i])) != NC_NOERR) {
2312 if ((nc_ret = nc_get_att_int(flags_gid, flags_varid, "flag_masks", (int*) flag_masks)) != NC_NOERR) {
2318 if ((nc_ret = nc_inq_att(flags_gid, flags_varid, "flag_meanings", &att_xtype, &attr_length)) != NC_NOERR) {
2324 if ((nc_ret = nc_get_att_text(flags_gid, flags_varid, "flag_meanings", flag_string)) != NC_NOERR) {
2426 olog_debug(arguments->log, "%s failed (%.3f < %f)\n", flag_meanings[flag_i], arguments->l2qc_thresholds[i], flag_percent);
2428 // olog_debug(arguments->log, "%s clear (%.3f > %f)\n", flag_meanings[flag_i], arguments->l2qc_thresholds[i], flag_percent);
2465 sprintf(region->ascii_time, "%04d-%02d-%02d %02d:%02d:%02d.%03d", t.tm_year + 1900, t.tm_mon + 1, t.tm_mday, t.tm_hour, t.tm_min, t.tm_sec, msec % 1000);
2473 int callback_ret = arguments->val_extract_parser(VALEXTRACT_KEY_FILE, region, arguments->user_input);
2490 static double process_scan_line_att(val_extract_arguments *arguments, nc_region *region, const char *name) {
2506 if ((nc_ret = nc_get_var1_double(gid, varid, ®ion->center.line, &line_value)) != NC_NOERR) {
2515 static double process_location_var(val_extract_arguments *arguments, nc_region *region, const char *name) {
2531 if ((nc_ret = nc_get_var1_double(gid, varid, ®ion->center.line, ¢er_value)) != NC_NOERR) {
2696 if ((nc_ret = nc_get_vara ## suffix(ncid, varid, region->boxes[i].start, region->boxes[i].count, p)) != NC_NOERR){ \
an array had not been initialized Several spelling and grammar corrections were which is read from the appropriate MCF the above metadata values were hard coded A problem calculating the average background DN for SWIR bands when the moon is in the space view port was corrected The new algorithm used to calculate the average background DN for all reflective bands when the moon is in the space view port is now the same as the algorithm employed by the thermal bands For non SWIR changes in the averages are typically less than Also for non SWIR the black body DNs remain a backup in case the SV DNs are not available For SWIR the changes in computed averages were larger because the old which used the black body suffered from contamination by the micron leak As a consequence of the if SV DNs are not available for the SWIR the EV pixels will not be the granule time is used to identify the appropriate tables within the set given for one LUT the first two or last two tables respectively will be used for the interpolation If there is only one LUT in the set of it will be treated as a constant LUT The manner in which Earth View data is checked for saturation was changed Previously the raw Earth View DNs and Space View DNs were checked against the lookup table values contained in the table dn_sat The change made is to check the raw Earth and Space View DNs to be sure they are less than the maximum saturation value and to check the Space View subtracted Earth View dns against a set of values contained in the new lookup table dn_sat_ev The metadata configuration and ASSOCIATEDINSTRUMENTSHORTNAME from the MOD02HKM product The same metatdata with extensions and were removed from the MOD021KM and MOD02OBC products ASSOCIATEDSENSORSHORTNAME was set to MODIS in all products These changes are reflected in new File Specification which users may consult for exact the pow functions were eliminated in Emissive_Cal and Emissive bands replaced by more efficient code Other calculations throughout the code were also made more efficient Aside from a few round off there was no difference to the product The CPU time decreased by about for a day case and for a night case A minor bug in calculating the uncertainty index for emissive bands was corrected The frame index(0-based) was previously being used the frame number(1-based) should have been used. There were only a few minor changes to the uncertainty index(maximum of 1 digit). 3. Some inefficient arrays(Sigma_RVS_norm_sq) were eliminated and some code lines in Preprocess_L1A_Data were moved into Process_OBCEng_Emiss. There were no changes to the product. Required RAM was reduced by 20 MB. Now
int olog_crit(olog *olog,...)
Master structure containing options, document strings, child parsers, and text filters....
Definition: argpar.h:398
Definition: val_extract.h:253
Definition: val_extract.h:273
#define VALEXTRACT_ERR_FLAG
Returned when the something goes wrong processing l2_flags.
Definition: val_extract.h:37
Definition: val_extract.h:241
#define VALEXTRACT_ERR_POINT_NOT_FOUND
Returned when the desired point is not in the file boundaries.
Definition: val_extract.h:28
These are used to scale the SD before writing it to the HDF4 file The default is and which means the product is not scaled at all Since the product is usually stored as a float inside of this is a way to write the float out as a integer l2prod min
Definition: HOWTO_Add_a_product.txt:76
#define OPTION_DOC_NO_BREAK
Do not add an extra newline after this documentation string. Useful for lists and manual formatting.
Definition: argpar.h:171
Definition: argpar.c:41
#define OPTION_INT
Cast this option as a long. The value and any error will be reflected in the argpar_state struct duri...
Definition: argpar.h:160
Definition: val_extract.h:233
Provides a single function to calculate geographical distances.
#define ARGPAR_ERR_USAGE
Returned from the parser callback to signal argpar to stop parsing, print a usage summary,...
Definition: argpar.h:338
Definition: pqueue-ll.c:14
Passed into the library function to control the processing. Many of the fields will be unspecified.
Definition: val_extract.h:103
double vincenty_distance(double lat1, double lon1, double lat2, double lon2)
Calculate geographical distances using Vincenty's algorithm.
Definition: vincenty.c:47
#define ARGPAR_KEY_SUCCESS
Passed as the key to each parser callback function when parsing has finished and no errors were retur...
Definition: argpar.h:295
Given to val_extract_arguments, these contain the valid ranges, inclusive, of variables....
Definition: val_extract.h:87
const char * val_extract_api_version()
Returns a string representation of the library's implemented API version number, without a label.
Definition: val_extract.c:2635
int shash_set(shash *h, const char *key, const char *value)
Add or overwrite a pointer, associating it with the given key.
Definition: shash.c:224
#define ARGPAR_KEY_INIT
Passed as the key to each parser callback function before any parsing occurs. For most cases,...
Definition: argpar.h:287
const char * val_extract_version()
Returns a string representation of the library's version number, without a label.
Definition: val_extract.c:2632
#define VALEXTRACT_KEY_INIT
Passed to parser when beginning the processing.
Definition: val_extract.h:50
A simple logger, capable of dispatching log events to multiple end points.
struct packet_stats stats
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 file
Definition: HISTORY.txt:413
int olog_debug(olog *olog,...)
int state(double tjdTDB, JPLIntUtilType *util, double posvel[13][6], double *pnut)
MOD_PR02AQUA Production where MYD is the prefix denoting AQUA file output The total
Definition: MOD_PR02AQUA_pr.txt:5
#define VALEXTRACT_ERR_VARIABLE
Returned when the something goes wrong processing a product or when finding a product specified on th...
Definition: val_extract.h:40
#define OPTION_HIDDEN
Do not display this option anywhere in the usage summary.
Definition: argpar.h:149
#define VALEXTRACT_KEY_VAR
Passed to parser when a variable is processed. The parser is passed a pointer to an nc_var structure ...
Definition: val_extract.h:56
#define ARGPAR_ERR_ABORT
Returned from the parser callback to signal argpar to stop parsing and return to the caller.
Definition: argpar.h:334
int closest_index(vector< float > const &refvals, const float value)
Definition: get_mld.cpp:198
int errno
subroutine diff(x, conec, n, dconecno, dn, dconecmk, units, u, inno, i, outno, o, input, deriv)
Definition: ffnet.f:205
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
no change in intended resolving MODur00064 Corrected handling of bad ephemeris attitude data
Definition: HISTORY.txt:356
argpar val_extract_argpar
argpar structure used for making programs that inherit options from this library.
Definition: val_extract.c:523
#define OPTION_DOC
This option isn't actually an option, merely text for the usage summary.
Definition: argpar.h:152
#define VALEXTRACT_ERR_L2QC
Not a real error, but returned when the L2QC step says it's a poor quality file.
Definition: val_extract.h:44
State variable to be filled before each call to the parser callback.
Definition: argpar.h:196
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 offsets between the high resolution geolocation and a bi linear interpolation extrapolation of the positions This can be used to reconstruct the high resolution geolocation Resolved Bug by delaying cumulation of gflags until after validation of derived products Resolved Bug by setting Latitude and Longitude to the correct fill resolving to support Near Real Time because they may be unnecessary if use of entrained ephemeris and attitude data is turned resolving bug report Corrected to filter out Aqua attitude records with missing status helping resolve bug MOD_PR03 will still correctly write scan and pixel data that does not depend upon the start time
Definition: HISTORY.txt:248
A simple dictionary library for storing strings.
#define VALEXTRACT_UNSET
Initial value for location arguments (lat/lon/line/pixl) before argument parsing.
Definition: val_extract.h:68
size_t nc_get_region_dim_size(nc_region *region, int dim_index)
Definition: val_extract.c:2683
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)
#define VALEXTRACT_ERR_NCFILE_INVALID
Returned when the NetCDF file isn't in the format expected (not an L2, etc).
Definition: val_extract.h:35
Library for reading command-line arguments in the form of key=value.
Definition: val_extract.c:1079
Definition: val_extract.h:266
Process a small section of a Level-2 NetCDF file.
int val_extract(val_extract_arguments *arguments)
Process a small section of a Level-2 NetCDF file.
Definition: val_extract.c:589
void unflatten_index(int index, int ndims, const int *dims, int *result)
Given dimension lengths from an nc_file and a one dimensional index, find the corresponding n-dimensi...
Definition: val_extract.c:2604
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 per delivery and then split off a new MYD_PR03 pcf file for Aqua Added AssociatedPlatformInstrumentSensor to the inventory metadata in MOD01 mcf and MOD03 mcf Created new versions named MYD01 mcf and MYD03 where AssociatedPlatformShortName is rather than Terra The program itself has been changed to read the Satellite Instrument validate it against the input L1A and LUT and to use it determine the correct files to retrieve the ephemeris and attitude data from Changed to produce a LocalGranuleID starting with MYD03 if run on Aqua data Added the Scan Type file attribute to the Geolocation copied from the L1A and attitude_angels to radians rather than degrees The accumulation of Cumulated gflags was moved from GEO_validate_earth_location c to GEO_locate_one_scan c
Definition: HISTORY.txt:464
#define VALEXTRACT_ERR_NCFILE_ERR
Returned when the NetCDF file can't be opened (due to errors or corruption).
Definition: val_extract.h:33
int val_extract_clean(val_extract_arguments *arguments)
Clean up stuff malloc'd by the argpar callback. Should be called at the end of processing if val_extr...
Definition: val_extract.c:2540
long timezone
#define VALEXTRACT_ERR_UNKNOWN
Returned for unexpected errors like malloc failures or, possibly, permissions problems and the like.
Definition: val_extract.h:31
#define VALEXTRACT_KEY_FILE
Passed to parser when first opening the NetCDF file. The parser is passed a pointer to an nc_region s...
Definition: val_extract.h:53
void val_extract_clear_args(val_extract_arguments *arguments)
Clear an argument struct to make it suitable for using the library without using argpar.
Definition: val_extract.c:127
How many dimensions is the output array Default is Not sure if anything above will work correctly strcpy(l2prod->title, "no title yet")
int olog_notice(olog *olog,...)
#define OPTION_DBL
Cast this option as a double. The value and any error will be reflected in the argpar_state struct du...
Definition: argpar.h:156
Definition: val_extract.h:237
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 attributes
Definition: HISTORY.txt:65