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)
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);
254 : declutter_rsp(false)
263 class Scans :
public std::vector<PolarScan<T>>
287 template<
typename OT>
291 this->units = v.
units;
293 this->reserve(v.size());
295 for (
const auto& src_scan : v)
335 if (!this->empty() && elevation <= this->back().
elevation)
337 LOG_CATEGORY(
"radar.io");
339 throw std::runtime_error(
"elevation not greather than the last one");
359 if (idx < this->size())
363 LOG_CATEGORY(
"radar.io");
364 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);
365 throw std::runtime_error(
"beam_size mismatch");
369 LOG_CATEGORY(
"radar.io");
370 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);
371 throw std::runtime_error(
"beam_size mismatch");
375 if (idx > this->size())
379 while (this->size() < idx)
400 if (elevations.size() < this->size())
402 LOG_CATEGORY(
"radar.io");
403 LOG_ERROR(
"normalize_elevations: standard elevation array has %zd elements, but we have %zd scans",
404 elevations.size(), this->size());
405 throw std::runtime_error(
"not enough standard elevations");
409 for (
size_t i = 0; i < this->size() - 1; ++i)
411 if (abs(elevations[i] - this->at(i).
elevation) > abs(elevations[i] - this->at(i + 1).
elevation))
413 LOG_CATEGORY(
"radar.io");
414 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);
415 throw std::runtime_error(
"real elevation is too different than standard elevations");
419 for (
size_t i = 0; i < this->size(); ++i)
420 this->at(i).elevation = elevations[i];
450 template<
typename OT>
460 for (
const auto& scan : *
this)
461 res = std::max(res, scan.beam_size);
468 double cell_size = this->at(0).cell_size;
469 for (
size_t i = 1; i < this->size(); ++i)
470 if ( this->at(i).cell_size !=
cell_size)
return false;
477 return this->front().elevation;
483 return this->back().elevation;
494 unsigned size_z = std::max(this->size(), (
size_t)slice.rows());
495 for (
unsigned el = 0; el < size_z; ++el)
496 this->scan(el).read_beam(az, slice.row_ptr(el), slice.cols(), missing_value);
502 stats.count_zeros.resize(this->size());
503 stats.count_ones.resize(this->size());
504 stats.count_others.resize(this->size());
505 stats.sum_others.resize(this->size());
507 for (
unsigned iel = 0; iel < this->size(); ++iel)
509 stats.count_zeros[iel] = 0;
510 stats.count_ones[iel] = 0;
511 stats.count_others[iel] = 0;
512 stats.sum_others[iel] = 0;
514 for (
unsigned iaz = 0; iaz < this->scan(iel).beam_count; ++iaz)
516 for (
size_t i = 0; i < this->scan(iel).beam_size; ++i)
521 case 0: stats.count_zeros[iel]++;
break;
522 case 1: stats.count_ones[iel]++;
break;
524 stats.count_others[iel]++;
525 stats.sum_others[iel] += val;
568 for(
unsigned el=0;el<this->size();el++)
570 this->scan(el)*=coefficient;
581 for (
unsigned el=0;el<this->size();el++)
583 this->scan(el)+=addend[el];
589 void resize_elev_fin();
601 extern template class PolarScan<double>;
602 extern template class Volume<double>;
604 extern template class Scans<double>;
PolarScan(const PolarScan &s)
Constructor Create a copy of a PolarScan.
void resize_beams_and_propagate_last_bin(unsigned new_beam_size)
Enlarges the PolarScan increasing beam_size and propagating the last bin value.
double nodata
Value used as 'no data' value.
double undetect
Minimum amount that can be measured.
double offset
Conversion factor.
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))
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...
T get(unsigned az, unsigned beam) const
Get a beam value.
double gain
Conversion factor.
void set(unsigned az, unsigned beam, T val)
Set a beam value.
PolarScan - structure to describe a polarScan containing a matrix of data and conversion factors.
void compute_stats(VolumeStats &stats) const
Compute Volume statistics.
Volume(unsigned beam_count)
Constructor.
double elevation_max() const
Return the highest elevation.
PolarScan< T > & append_scan(unsigned beam_size, double elevation, double cell_size)
Append a scan to this volume.
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.
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.
Volume & operator*=(const T coefficient)
*= operator defined
const unsigned max_beam_size() const
Return the maximum beam size in all PolarScans.
Volume(const Volume< OT > &v, const T &default_value)
Copy constructor.
double elevation_min() const
Return the lowest elevation.
Volume & operator+=(Volume &addend)
+= operator defined
const unsigned beam_count
Number of beam_count used ast each elevations.
bool is_unique_cell_size() const
Test if same cell_size in all PolarScans.
Homogeneous volume with a common beam count for all PolarScans.
static unsigned char DBtoBYTE(double DB, double gain=80./255., double offset=-20.)
funzione che converte dB in valore intero tra 0 e 255
static constexpr double BYTEtoDB(unsigned char DBZbyte, double gain=80./255., double offset=-20.)
funzione che converte Z unsigned char in DBZ
const PolarScan< T > & scan(unsigned idx) const
Access a polar scan (const)
void SetOffset(T offset)
set offset value
RadarSite radarSite
RadarSite.
Scans(const Scans< OT > &v, const T &default_value)
Constructor Copy from another Scans.
std::string units
Data units according to ODIM documentation.
PolarScan< T > & append_scan(unsigned beam_count, unsigned beam_size, double elevation, double cell_size, const T &default_value=algo::DBZ::BYTEtoDB(1))
Append a scan to this volume.
PolarScan< T > & scan(unsigned idx)
Access a polar scan.
std::string quantity
Odim quantity name.
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.
void normalize_elevations(const std::vector< double > &elevations)
Change the elevations in the PolarScans to match the given elevation vector.
std::shared_ptr< LoadInfo > load_info
Polar volume information.
Sequence of PolarScans which can have a different beam count for each elevation.
Base for all matrices we use, since we rely on row-major data.
double diff_height(unsigned rg_start, unsigned rg_end)
Height difference in kilometers (legacy) between two range gates.
unsigned beam_size
Number of samples in each beam.
double elevation
Nominal elevation of this PolarScan, which may be different from the effective elevation of each sing...
double height(unsigned rg, double beam_half_width=0.0)
Height in kilometers (legacy) at range gate for beam elevation + beam_half_width.
Eigen::VectorXd elevations_real
Vector of actual elevations for each beam.
unsigned beam_count
Count of beams in this scan.
Eigen::VectorXd azimuths_real
Vector of actual azimuths for each beam.
double cell_size
Size of a beam cell in meters.
double sample_height(unsigned cell_idx) const
Return the height (in meters) of the sample at the given cell indexa.
Basic structure to describe a polar scan, independently of the type of its samples.
time_t acq_date
Acquisition date.
std::string source_name
radar source name in capital letters (SPC or GAT)
std::string filename
Original file name.
bool declutter_rsp
flag true if data have been decluttered with Doppler at rsp level
LoadInfo structure - Contains generic volume information.