Elaboradar  0.1

◆ load()

void radarelab::volume::ODIMLoader::load ( const std::string &  pathname)

Load method.

Parametri
[in]pathname- full path for data file

Definizione alla linea 34 del file odim.cpp.

35 {
36  LOG_CATEGORY("radar.io");
37 
38  namespace odim = OdimH5v21;
39  using namespace Radar;
40  using namespace std;
41 
42  shared_ptr<LoadInfo> load_info = make_shared<LoadInfo>();
43  load_info->filename = pathname;
44 
45  unique_ptr<odim::OdimFactory> factory(new odim::OdimFactory());
46  unique_ptr<odim::PolarVolume> volume(factory->openPolarVolume(pathname));
47 
48  load_info->acq_date = volume->getDateTime();
49 
50  double range_scale = 0;
51 
52  // Iterate all scans
53  unsigned scan_count = int_to_unsigned(volume->getScanCount(), "scan count");
54  double old_elevation = -1000.;
55  for (unsigned src_elev = 0; src_elev < scan_count; ++src_elev)
56  {
57  unique_ptr<odim::PolarScan> scan(volume->getScan(src_elev));
58  double elevation = scan->getEAngle();
59  Available_Elevations.push_back(elevation);
60  // FIXME: please add a comment on why this is needed: are there faulty
61  // ODIM files out there which repeat elevations? Is it correct that
62  // only the first elevation is used and not, say, the last one?
63  if( elevation == old_elevation ) continue;
64  old_elevation=elevation;
65  // Read and and validate resolution information
66  if (src_elev == 0)
67  range_scale = scan->getRangeScale();
68  else {
69  double rs = scan->getRangeScale();
70  if (rs != range_scale)
71  {
72  LOG_ERROR("scan %d (elevation %f) has rangeScale %f that is different from %f in the previous scans",
73  src_elev, elevation, rs, range_scale);
74  throw runtime_error("rangeScale mismatch");
75  }
76  }
77 
78  // Get and validate the azimuth angles for this scan
79  std::vector<odim::AZAngles> azangles = scan->getAzimuthAngles();
80  int rpm_sign = scan->getDirection();
81 
82  std::vector<double> elevation_angles = scan->getElevationAngles();
83 
84  unsigned beam_count = int_to_unsigned(scan->getNumRays(), "number of rays");
85  if (azangles.size() != beam_count)
86  {
87  LOG_ERROR("elevation %f has %zd azimuth angles and %d rays", elevation, azangles.size(), beam_count);
88  throw runtime_error("mismatch between number of azumuth angles and number of rays");
89  }
90 
91  unsigned beam_size = int_to_unsigned(scan->getNumBins(), "beam size");
92 
93  // Read all quantities that have been requested
94  for (auto& todo : to_load)
95  {
96  // Create azimuth maps and PolarScan objects for this elevation
97  const string& name = todo.first;
98  Scans<double>& target = *todo.second;
99 
100  // Pick the best quantity among the ones available
101  if (!scan->hasQuantityData(name))
102  {
103  LOG_WARN("no %s found for elevation angle %f: skipping", name.c_str(), elevation);
104  continue;
105  }
106  PolarScan<double>& vol_pol_scan = target.append_scan(beam_count, beam_size, elevation, range_scale);
107 
108  unique_ptr<odim::PolarScanData> data(scan->getQuantityData(name));
109 
110  // Fill/overwrite variable metadata at volume level
111  target.quantity = name;
112  target.radarSite.height_r = volume->getAltitude()/1000.;
113  target.radarSite.antennaTowerHeight = 0.;
114  // Fill variable metadata at scan level
115  vol_pol_scan.nodata = data->getNodata() * data->getGain() + data->getOffset();
116  vol_pol_scan.undetect = data->getUndetect() * data->getGain() + data->getOffset();
117  vol_pol_scan.gain = data->getGain();
118  vol_pol_scan.offset = data->getOffset();
119  vol_pol_scan.cell_size = scan->getRangeScale();
120 
121  // Read actual data from ODIM
122  odim::RayMatrix<double> matrix;
123  matrix.resize(beam_count, beam_size);
124  data->readTranslatedData(matrix);
125 
126  for (unsigned src_az = 0; src_az < beam_count; ++src_az)
127  {
128  Eigen::VectorXd beam(beam_size);
129 
130  for (unsigned i = 0; i < beam_size; ++i)
131  beam(i) = matrix.elem(src_az, i);
132 
133  vol_pol_scan.row(src_az) = beam;
134  vol_pol_scan.elevations_real(src_az) = elevation_angles[src_az];
135  vol_pol_scan.azimuths_real(src_az) = azangles[src_az].averagedAngle(rpm_sign);
136  }
137  }
138  }
139  for (auto& i: to_load)
140  {
141  i.second->load_info = load_info;
142  }
143 }
std::map< std::string, Scans< double > * > to_load
Map used to specify quantity to be loaded.
Definition: loader.h:26

Referenzia radarelab::volume::Scans< T >::append_scan(), radarelab::PolarScanBase::azimuths_real, radarelab::PolarScanBase::cell_size, radarelab::PolarScanBase::elevations_real, radarelab::PolarScan< T >::gain, radarelab::PolarScan< T >::nodata, radarelab::PolarScan< T >::offset, radarelab::volume::Scans< T >::quantity, radarelab::volume::Scans< T >::radarSite, e radarelab::PolarScan< T >::undetect.

Referenziato da radarelab::volume::classifier::classifier(), e elaboradar::CUM_BAC::read_odim_volume().