NASA Logo
Ocean Color Science Software

ocssw V2022
geo_region.cpp
Go to the documentation of this file.
1 #include "geo_region.h"
2 #include "l12_proto.h"
3 #include <netcdf>
4 #include <string>
5 #include <iostream>
6 #include <vector>
7 
8 #define ERROR_EXIT \
9  { \
10  std::cerr << "\n See " << __LINE__ << " in file " << __FILE__ << ". Exiting...\n"; \
11  georegion_file.close(); \
12  exit(EXIT_FAILURE); \
13  }
14 #define CHECK_BOUNDS(max_val, min_val) \
15  { \
16  if (min_val > max_val) { \
17  std::cerr << "--Error--: " << #min_val << "=" << min_val << " is larger than " << #max_val << "=" \
18  << max_val; \
19  ERROR_EXIT; \
20  } \
21  }
22 namespace {
23 netCDF::NcFile georegion_file;
24 netCDF::NcVar georegion_variable;
25 netCDF::NcVar lat_variable;
26 netCDF::NcVar lon_variable;
27 size_t nlat;
28 size_t nlon;
29 std::vector<double> latitude;
30 std::vector<double> longitude;
31 double step_lat;
32 double step_lon;
33 double min_lon;
34 double max_lon;
35 double min_lat;
36 double max_lat;
37 } // namespace
38 
39 void read_variable(const netCDF::NcFile &file, netCDF::NcVar &var, const std::string &varname) {
40  var = file.getVar(varname);
41  if (var.isNull()) {
42  std::cerr << "--Error--: variable " << varname << " is not found in the georegion file";
43  ERROR_EXIT;
44  }
45 }
46 
48  georegion_file.close();
49 }
50 
51 int get_georegion(float lat, float lon) {
52  if (georegion_variable.isNull()) {
53  std::cout << "Loading the georegion file: " << input->georegionfile << std::endl;
54  georegion_file.open(input->georegionfile, netCDF::NcFile::read);
55  read_variable(georegion_file, georegion_variable, "georegion");
56  read_variable(georegion_file, lat_variable, "lat");
57  read_variable(georegion_file, lon_variable, "lon");
58  std::vector<netCDF::NcDim> dims = georegion_variable.getDims();
59  if (dims.size() != 2) {
60  std::cerr << "--Error-- : The georegion variable should be a two dimensional variable.";
61  ERROR_EXIT;
62  }
63  if (dims.at(0).getName() != "lat" || dims.at(1).getName() != "lon") {
64  std::cerr << "--Error-- : The first dimension of the georegion should be lat, the second one "
65  "should be lon. The dimensions found in the geofile are: first \""
66  << dims.at(0).getName() << "\" and second \"" << dims.at(1).getName() << "\"";
67  ERROR_EXIT;
68  }
69  nlat = dims.at(0).getSize();
70  nlon = dims.at(1).getSize();
71  std::vector<netCDF::NcDim> dim_lat = lat_variable.getDims();
72  std::vector<netCDF::NcDim> dim_lon = lon_variable.getDims();
73  if (dim_lat.size() != 1) {
74  std::cerr << "--Error-- : The latitude variable should be a one dimensional variable.";
75  ERROR_EXIT;
76  }
77  if (dim_lon.size() != 1) {
78  std::cerr << "--Error-- : The latitude variable should be a one dimensional variable.";
79  ERROR_EXIT;
80  }
81  if (dim_lat.at(0).getName() != "lat" || dim_lon.at(0).getName() != "lon") {
82  std::cerr << "--Error-- : The dimension mismatch between latitude/longitude and the georegion";
83  ERROR_EXIT;
84  }
85  // checking for datatype
86  if (netCDF::NcType::nc_BYTE != georegion_variable.getType().getTypeClass()) {
87  std::cerr << "--Error-- : The datatype of the georegion should be signed byte";
88  ERROR_EXIT;
89  };
90  if (netCDF::NcType::nc_DOUBLE != lat_variable.getType().getTypeClass()) {
91  std::cerr << "--Error-- : The datatype of the latitude should be double";
92  ERROR_EXIT;
93  };
94  if (netCDF::NcType::nc_DOUBLE != lon_variable.getType().getTypeClass()) {
95  std::cerr << "--Error-- : The datatype of the longitude should be double";
96  ERROR_EXIT;
97  };
98  latitude = std::vector<double>(nlat);
99  longitude = std::vector<double>(nlon);
100  lat_variable.getVar(latitude.data());
101  lon_variable.getVar(longitude.data());
102  step_lat = latitude[1] - latitude[0];
103  step_lon = longitude[1] - longitude[0];
104  if (step_lat > 0) {
105  max_lat = latitude[nlat - 1];
106  min_lat = latitude[0];
107  } else {
108  min_lat = latitude[nlat - 1];
109  max_lat = latitude[0];
110  }
111  if (step_lon > 0) {
112  max_lon = longitude[nlon - 1];
113  min_lon = longitude[0];
114  } else {
115  min_lon = longitude[nlon - 1];
116  max_lon = longitude[0];
117  }
118  netCDF::NcGroupAtt geospatial_lat_min = georegion_file.getAtt("geospatial_lat_min");
119  netCDF::NcGroupAtt geospatial_lat_max = georegion_file.getAtt("geospatial_lat_max");
120  netCDF::NcGroupAtt geospatial_lon_min = georegion_file.getAtt("geospatial_lon_min");
121  netCDF::NcGroupAtt geospatial_lon_max = georegion_file.getAtt("geospatial_lon_max");
122  if (!geospatial_lat_min.isNull()) {
123  geospatial_lat_min.getValues(&min_lat);
124  }
125  if (!geospatial_lat_max.isNull()) {
126  geospatial_lat_max.getValues(&max_lat);
127  }
128  if (!geospatial_lon_min.isNull()) {
129  geospatial_lon_min.getValues(&min_lon);
130  }
131  if (!geospatial_lon_max.isNull()) {
132  geospatial_lon_max.getValues(&max_lon);
133  }
134  CHECK_BOUNDS(max_lat,min_lat);
135  CHECK_BOUNDS(max_lon,min_lon);
136  }
137  if (lat > max_lat || lat < min_lat)
138  return 0;
139  if (lon > max_lon || lon < min_lon)
140  return 0;
141  // should be uniform meshgrid
142  size_t ilat = static_cast<size_t>(std::round((lat - latitude[0]) / step_lat));
143  size_t ilon = static_cast<size_t>(std::round((lon - longitude[0]) / step_lon));
144  // takes care of the edge cases
145 
146  std::vector<size_t> start = {ilat, ilon};
147  std::vector<size_t> count = {1, 1};
148  int8_t flag = 0;
149  georegion_variable.getVar(start, count, &flag);
150  // if (flag == 0)
151  // {
152  // std::cout << ilat << " " << ilon << " " << lat << " " << lon << " " << latitude[0] << " " <<
153  // longitude[0] << std::endl;
154  // }
155  return flag;
156 }
void read_variable(const netCDF::NcFile &file, netCDF::NcVar &var, const std::string &varname)
Definition: geo_region.cpp:39
int get_georegion(float lat, float lon)
Definition: geo_region.cpp:51
real(single), dimension(:,:), allocatable longitude
real(single), dimension(:,:), allocatable latitude
#define CHECK_BOUNDS(max_val, min_val)
Definition: geo_region.cpp:14
@ string
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
instr * input
void close_georegion_file()
Definition: geo_region.cpp:47
#define ERROR_EXIT
Definition: geo_region.cpp:8
double max_lon
Definition: GEO_DEM.c:64
double min_lat
Definition: GEO_DEM.c:63
int count
Definition: decode_rs.h:79