6 #ifndef RADARELAB_VOLUME_H
7 #define RADARELAB_VOLUME_H
70 double height(
unsigned rg,
double beam_half_width=0.0);
78 double diff_height(
unsigned rg_start,
unsigned rg_end);
161 T
get(
unsigned az,
unsigned beam)
const
163 return (*
this)(az, beam);
170 void set(
unsigned az,
unsigned beam, T val)
172 (*this)(az, beam) = val;
194 void read_beam(
unsigned az, T* out,
unsigned out_size, T missing=0)
const
199 size_t set_count = min(beam_size, out_size);
201 for (
unsigned i = 0; i < set_count; ++i)
204 for (
unsigned i = set_count; i < out_size; ++i)
214 if (new_beam_size <= beam_size)
return;
215 this->conservativeResize(Eigen::NoChange, new_beam_size);
216 this->rightCols(new_beam_size - this->beam_size).colwise() = this->col(this->beam_size - 1);
217 this->beam_size = new_beam_size;
224 std::vector<unsigned> count_zeros;
225 std::vector<unsigned> count_ones;
226 std::vector<unsigned> count_others;
227 std::vector<unsigned> sum_others;
229 void print(FILE* out);
252 : declutter_rsp(false)
261 class Scans :
public std::vector<PolarScan<T>>
283 template<
typename OT>
287 this->units = v.
units;
289 this->reserve(v.size());
291 for (
const auto& src_scan : v)
320 if (!this->empty() && elevation <= this->back().elevation)
322 LOG_CATEGORY(
"radar.io");
323 LOG_ERROR(
"append_scan(beam_count=%u, beam_size=%u, elevation=%f, cell_size=%f) called with an elevation that is not above the last one (%f)", beam_count, beam_size, elevation, cell_size, this->back().elevation);
324 throw std::runtime_error(
"elevation not greather than the last one");
344 if (idx < this->size())
346 if (beam_count != (*
this)[idx].beam_count)
348 LOG_CATEGORY(
"radar.io");
349 LOG_ERROR(
"make_scan(idx=%u, beam_count=%u, beam_size=%u) called, but the scan already existed with beam_count=%u", idx, beam_count, beam_size, (*
this)[idx].beam_count);
350 throw std::runtime_error(
"beam_size mismatch");
352 if (beam_size != (*
this)[idx].beam_size)
354 LOG_CATEGORY(
"radar.io");
355 LOG_ERROR(
"make_scan(idx=%u, beam_count=%u, beam_size=%u) called, but the scan already existed with beam_size=%u", idx, beam_count, beam_size, (*
this)[idx].beam_size);
356 throw std::runtime_error(
"beam_size mismatch");
360 if (idx > this->size())
364 while (this->size() < idx)
365 this->push_back(
PolarScan<T>(beam_count, this->back().beam_size));
385 if (elevations.size() < this->size())
387 LOG_CATEGORY(
"radar.io");
388 LOG_ERROR(
"normalize_elevations: standard elevation array has %zd elements, but we have %zd scans",
389 elevations.size(), this->size());
390 throw std::runtime_error(
"not enough standard elevations");
394 for (
size_t i = 0; i < this->size() - 1; ++i)
396 if (abs(elevations[i] - this->at(i).
elevation) > abs(elevations[i] - this->at(i + 1).elevation))
398 LOG_CATEGORY(
"radar.io");
399 LOG_ERROR(
"normalize_elevations: elevation %zd (%f) should be set to %f but it would make it closer to the next elevation %f", i, this->at(i).elevation, elevations[i], this->at(i + 1).elevation);
400 throw std::runtime_error(
"real elevation is too different than standard elevations");
404 for (
size_t i = 0; i < this->size(); ++i)
405 this->at(i).elevation = elevations[i];
426 : beam_count(beam_count)
435 template<
typename OT>
445 for (
const auto& scan : *
this)
446 res = std::max(res, scan.beam_size);
453 double cell_size = this->at(0).cell_size;
454 for (
size_t i = 1; i < this->size(); ++i)
455 if ( this->at(i).cell_size !=
cell_size)
return false;
462 return this->front().elevation;
468 return this->back().elevation;
479 unsigned size_z = std::max(this->size(), (
size_t)slice.rows());
480 for (
unsigned el = 0; el < size_z; ++el)
481 this->scan(el).read_beam(az, slice.row_ptr(el), slice.cols(), missing_value);
487 stats.count_zeros.resize(this->size());
488 stats.count_ones.resize(this->size());
489 stats.count_others.resize(this->size());
490 stats.sum_others.resize(this->size());
492 for (
unsigned iel = 0; iel < this->size(); ++iel)
494 stats.count_zeros[iel] = 0;
495 stats.count_ones[iel] = 0;
496 stats.count_others[iel] = 0;
497 stats.sum_others[iel] = 0;
499 for (
unsigned iaz = 0; iaz < this->scan(iel).beam_count; ++iaz)
501 for (
size_t i = 0; i < this->scan(iel).beam_size; ++i)
506 case 0: stats.count_zeros[iel]++;
break;
507 case 1: stats.count_ones[iel]++;
break;
509 stats.count_others[iel]++;
510 stats.sum_others[iel] += val;
553 for(
unsigned el=0;el<this->size();el++)
555 this->scan(el)*=coefficient;
566 for (
unsigned el=0;el<this->size();el++)
568 this->scan(el)+=addend[el];
574 void resize_elev_fin();
586 extern template class PolarScan<double>;
587 extern template class Volume<double>;
589 extern template class Scans<double>;
double gain
Conversion factor.
double undetect
Minimum amount that can be measured.
Eigen::VectorXd elevations_real
Vector of actual elevations for each beam.
PolarScan< T > & scan(unsigned idx)
Access a polar scan.
static constexpr double BYTEtoDB(unsigned char DBZbyte, double gain=80./255., double offset=-20.)
funzione che converte Z unsigned char in DBZ
void read_beam(unsigned az, T *out, unsigned out_size, T missing=0) const
Fill an array with beam data .
PolarScan(unsigned beam_count, unsigned beam_size, const T &default_value=algo::DBZ::BYTEtoDB(1))
void compute_stats(VolumeStats &stats) const
Compute Volume statistics.
Volume & operator*=(const T coefficient)
*= operator defined
PolarScan - structure to describe a polarScan containing a matrix of data and conversion factors...
void resize_beams_and_propagate_last_bin(unsigned new_beam_size)
Enlarges the PolarScan increasing beam_size and propagating the last bin value.
double cell_size
Size of a beam cell in meters.
unsigned beam_count
Count of beams in this scan.
PolarScan< T > & append_scan(unsigned beam_size, double elevation, double cell_size)
Append a scan to this volume.
std::string filename
Original file name.
Base for all matrices we use, since we rely on row-major data.
const unsigned beam_count
Number of beam_count used ast each elevations.
double offset
Conversion factor.
LoadInfo structure - Contains generic volume information.
std::shared_ptr< LoadInfo > load_info
Polar volume information.
Volume(const Volume< OT > &v, const T &default_value)
Copy constructor.
PolarScan< T > & append_scan(unsigned beam_count, unsigned beam_size, double elevation, double cell_size)
Append a scan to this volume.
void normalize_elevations(const std::vector< double > &elevations)
Change the elevations in the PolarScans to match the given elevation vector.
unsigned beam_size
Number of samples in each beam.
void read_vertical_slice(unsigned az, Matrix2D< T > &slice, double missing_value) const
Fill a matrix elevations x beam_size with the vertical slice at a given azimuth.
Basic structure to describe a polar scan, independently of the type of its samples.
double diff_height(unsigned rg_start, unsigned rg_end)
Height difference in kilometers (legacy) between two range gates.
double elevation_min() const
Return the lowest elevation.
Volume(unsigned beam_count)
Constructor.
std::string units
Data units according to ODIM documentation.
bool is_unique_cell_size() const
Test if same cell_size in all PolarScans.
Homogeneous volume with a common beam count for all PolarScans.
PolarScan(const PolarScan &s)
Constructor Create a copy of a PolarScan.
Sequence of PolarScans which can have a different beam count for each elevation.
void set(unsigned az, unsigned beam, T val)
Set a beam value.
bool declutter_rsp
flag true if data have been decluttered with Doppler at rsp level
double sample_height(unsigned cell_idx) const
Return the height (in meters) of the sample at the given cell indexa.
static unsigned char DBtoBYTE(double DB, double gain=80./255., double offset=-20.)
funzione che converte dB in valore intero tra 0 e 255
RadarSite radarSite
RadarSite.
Scans(const Scans< OT > &v, const T &default_value)
Constructor Copy from another Scans.
const unsigned max_beam_size() const
Return the maximum beam size in all PolarScans.
PolarScan< T > & make_scan(unsigned idx, unsigned beam_count, unsigned beam_size, double elevation, double cell_size)
Create or reuse a scan at position idx, with the given beam size.
std::string quantity
Odim quantity name.
Eigen::VectorXd azimuths_real
Vector of actual azimuths for each beam.
double sample_height_real(unsigned az, unsigned cell_idx) const
Return the height (in meters) of a sample given its azimuth and cell indices use the real beam elevat...
double nodata
Value used as 'no data' value.
double height(unsigned rg, double beam_half_width=0.0)
Height in kilometers (legacy) at range gate for beam elevation + beam_half_width. ...
const PolarScan< T > & scan(unsigned idx) const
Access a polar scan (const)
double elevation_max() const
Return the highest elevation.
PolarScan< T > & make_scan(unsigned idx, unsigned beam_size, double elevation, double cell_size)
Create or reuse a scan at position idx, with the given beam size.
time_t acq_date
Acquisition date.
Volume & operator+=(Volume &addend)
+= operator defined
double elevation
Nominal elevation of this PolarScan, which may be different from the effective elevation of each sing...