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  try
51  {
52  //string sourcename(volume->getSource().Place.substr(2).c_str());
53  //transform(sourcename.begin(), sourcename.end(), sourcename.begin(),::toupper);
54  //cout<<"volume getsource : "<<sourcename<<endl;
55 // string sourcename(volume->getSource().Place.c_str());
56 // cout<<"volume getsource : "<<sourcename<<endl;
57  load_info->source_name = volume->getSource().Place.c_str() ; //sourcename;
58  }
59  catch (std::exception& stde)
60  {
61  std::cerr << "Errore durante l'esecuzione: " << stde.what() << std::endl;
62  }
63  catch (...)
64  {
65  std::cerr << "Errore sconosciuto" << std::endl;
66  }
67 
68  double range_scale = 0;
69 
70  // Iterate all scans
71  unsigned scan_count = int_to_unsigned(volume->getScanCount(), "scan count");
72  double old_elevation = -1000.;
73  for (unsigned src_elev = 0; src_elev < scan_count; ++src_elev)
74  {
75  unique_ptr<odim::PolarScan> scan(volume->getScan(src_elev));
76  double elevation = scan->getEAngle();
77  Available_Elevations.push_back(elevation);
78  // FIXME: please add a comment on why this is needed: are there faulty
79  // ODIM files out there which repeat elevations? Is it correct that
80  // only the first elevation is used and not, say, the last one?
81  if( elevation == old_elevation ) continue;
82  old_elevation=elevation;
83  // Read and and validate resolution information
84  if (src_elev == 0)
85  range_scale = scan->getRangeScale();
86  else {
87  double rs = scan->getRangeScale();
88  if (rs != range_scale)
89  {
90  LOG_ERROR("scan %d (elevation %f) has rangeScale %f that is different from %f in the previous scans",
91  src_elev, elevation, rs, range_scale);
92  throw runtime_error("rangeScale mismatch");
93  }
94  }
95 
96  // Get and validate the azimuth angles for this scan
97  std::vector<odim::AZAngles> azangles = scan->getAzimuthAngles();
98  int rpm_sign = scan->getDirection();
99 
100  std::vector<double> elevation_angles = scan->getElevationAngles();
101 
102  unsigned beam_count = int_to_unsigned(scan->getNumRays(), "number of rays");
103  if (azangles.size() != beam_count)
104  {
105  LOG_ERROR("elevation %f has %zd azimuth angles and %d rays", elevation, azangles.size(), beam_count);
106  throw runtime_error("mismatch between number of azumuth angles and number of rays");
107  }
108 
109  unsigned beam_size = int_to_unsigned(scan->getNumBins(), "beam size");
110 
111  // Read all quantities that have been requested
112  for (auto& todo : to_load)
113  {
114  // Create azimuth maps and PolarScan objects for this elevation
115  const string& name = todo.first;
116  Scans<double>& target = *todo.second;
117 
118  // Pick the best quantity among the ones available
119  if (!scan->hasQuantityData(name))
120  {
121  LOG_WARN("no %s found for elevation angle %f: skipping", name.c_str(), elevation);
122  continue;
123  }
124  PolarScan<double>& vol_pol_scan = target.append_scan(beam_count, beam_size, elevation, range_scale);
125 
126  unique_ptr<odim::PolarScanData> data(scan->getQuantityData(name));
127 
128  // Fill/overwrite variable metadata at volume level
129  target.quantity = name;
130  target.radarSite.height_r = volume->getAltitude()/1000.;
131  target.radarSite.antennaTowerHeight = 0.;
132  // Fill variable metadata at scan level
133  vol_pol_scan.nodata = data->getNodata() * data->getGain() + data->getOffset();
134  vol_pol_scan.undetect = data->getUndetect() * data->getGain() + data->getOffset();
135  vol_pol_scan.gain = data->getGain();
136  vol_pol_scan.offset = data->getOffset();
137  vol_pol_scan.cell_size = scan->getRangeScale();
138 
139  // Read actual data from ODIM
140  odim::RayMatrix<double> matrix;
141  matrix.resize(beam_count, beam_size);
142  data->readTranslatedData(matrix);
143 
144  for (unsigned src_az = 0; src_az < beam_count; ++src_az)
145  {
146  Eigen::VectorXd beam(beam_size);
147 
148  for (unsigned i = 0; i < beam_size; ++i)
149  beam(i) = matrix.elem(src_az, i);
150 
151  vol_pol_scan.row(src_az) = beam;
152  vol_pol_scan.elevations_real(src_az) = elevation_angles[src_az];
153  vol_pol_scan.azimuths_real(src_az) = azangles[src_az].averagedAngle(rpm_sign);
154  }
155  }
156  }
157  for (auto& i: to_load)
158  {
159  i.second->load_info = load_info;
160  }
161 }
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().