1#ifndef CASACORE_UVW_FILE_H_
2#define CASACORE_UVW_FILE_H_
64 source.rows_per_block_ = 0;
65 source.active_block_ = 0;
66 source.reference_antenna_ = 0;
67 source.start_antenna_2_ = 0;
68 source.n_antennas_ = 0;
69 source.block_uvws_.clear();
70 source.block_is_changed_ =
false;
77 file_ = std::move(rhs.file_);
87 rhs.rows_per_block_ = 0;
88 rhs.active_block_ = 0;
89 rhs.reference_antenna_ = 0;
90 rhs.start_antenna_2_ = 0;
92 rhs.block_uvws_.clear();
93 rhs.block_is_changed_ =
false;
108 return UvwFile(filename,
true);
116 void WriteUvw(uint64_t row,
size_t antenna1,
size_t antenna2,
120 throw std::runtime_error(
121 "Uvw data must be written in order (writing row " +
122 std::to_string(row) +
", after writing " + std::to_string(
n_rows_) +
148 if (antenna1 != antenna2) {
151 const std::array<double, 3> ant2_uvw{uvw[0], uvw[1], uvw[2]};
155 const std::array<double, 3> ant1_uvw{-uvw[0], -uvw[1], -uvw[2]};
157 }
else if (
IsSet(antenna1)) {
160 const std::array<double, 3> ant1_uvw =
block_uvws_[antenna1];
161 const std::array<double, 3> ant2_uvw{
162 uvw[0] + ant1_uvw[0], uvw[1] + ant1_uvw[1], uvw[2] + ant1_uvw[2]};
164 }
else if (
IsSet(antenna2)) {
167 const std::array<double, 3> ant2_uvw =
block_uvws_[antenna2];
168 const std::array<double, 3> ant1_uvw{
169 ant2_uvw[0] - uvw[0], ant2_uvw[1] - uvw[1], ant2_uvw[2] - uvw[2]};
172 throw std::runtime_error(
173 "Baselines are written in a non-ordered way: they need to be "
174 "ordered either by antenna 1 or by antenna 2");
185 void ReadUvw(uint64_t row,
size_t antenna1,
size_t antenna2,
double* uvw) {
188 throw std::runtime_error(
189 "Invalid read for Uvw data: row " + std::to_string(row) +
190 ", baseline (" + std::to_string(antenna1) +
", " +
191 std::to_string(antenna2) +
") was requested. File has only " +
192 std::to_string(
n_rows_) +
" rows.");
226 sizeof(double) * 3)) {}
238 throw std::runtime_error(
239 "Uvw file has an incorrect number of rows (" +
240 std::to_string(
file_.
NRows()) +
", expecting multiple of " +
241 std::to_string(
n_antennas_ - 1) +
"): file corrupted?");
247 throw std::runtime_error(
248 "Invalid combination of values for n_antenna and reference antenna "
249 "in file: file damaged?");
262 void StoreOrCheck(
size_t antenna,
const std::array<double, 3>& antenna_uvw) {
263 if (
IsSet(antenna)) {
265 std::ostringstream msg;
266 msg <<
"Inconsistent UVW value written for antenna " << antenna
268 <<
", new value is " <<
UvwAsString(antenna_uvw) <<
".";
269 throw std::runtime_error(msg.str());
294 for (
size_t antenna = 0; antenna !=
n_antennas_; ++antenna) {
297 ? block_start_row + antenna
298 : block_start_row + antenna - 1;
299 std::array<double, 3>& uvw =
block_uvws_.emplace_back();
302 block_uvws_.emplace_back(std::array<double, 3>{0.0, 0.0, 0.0});
313 throw std::runtime_error(
"Trying to write an incomplete UVW block");
315 for (
size_t antenna = 0; antenna !=
n_antennas_; ++antenna) {
318 ? block_start_row + antenna
319 : block_start_row + antenna - 1;
330 throw std::runtime_error(
331 "The UVW columnar file header not have the expected tag for UVW "
332 "columns: the measurement set may be damaged");
336 n_antennas_ =
reinterpret_cast<uint64_t&
>(data[24]);
344 reinterpret_cast<uint64_t&
>(data[24]) =
n_antennas_;
352 static bool AreNear(std::array<double, 3> a, std::array<double, 3> b) {
356 const double magnitude = std::max({1e-5, std::fabs(a), std::fabs(b)});
357 return (std::fabs(a - b) / magnitude) < 1e-5;
359 static std::string
UvwAsString(
const std::array<double, 3>& uvw) {
360 std::ostringstream str;
361 str <<
"[" << uvw[0] <<
", " << uvw[1] <<
", " << uvw[2] <<
"]";
375 std::numeric_limits<double>::max(), std::numeric_limits<double>::max(),
376 std::numeric_limits<double>::max()};
Stores values of a UVW column in a compressed way.
std::string Filename() const
static constexpr size_t kHeaderSize
The header: char[8] "Uvw-col\0" (=kMagicHeaderTag) uint64_t rows_per_block uint64_t reference_antenna...
static UvwFile OpenExisting(const std::string &filename)
Open an already existing UVW file from disk with the given filename.
static constexpr const char kMagicHeaderTag[8]
static UvwFile CreateNew(const std::string &filename)
Create a new UVW file on disk with the given filename.
uint64_t rows_per_block_
A "block" is a contiguous number of baselines that together form one timestep.
void WriteUvw(uint64_t row, size_t antenna1, size_t antenna2, const double *uvw)
Write a single row to the column.
BufferedColumnarFile file_
uint64_t n_rows_
Number of rows in the Uvw column.
static bool AreNear(std::array< double, 3 > a, std::array< double, 3 > b)
std::vector< std::array< double, 3 > > block_uvws_
UVW for each antenna in the block.
static bool AreNear(double a, double b)
void StoreOrCheck(size_t antenna, const std::array< double, 3 > &antenna_uvw)
If this block does not have a value for the specified antenna, store the uvw value for it.
bool IsSet(size_t antenna) const
UvwFile(const std::string &filename)
Create a new file on disk.
static constexpr std::array< double, 3 > kUnsetPosition
UvwFile & operator=(UvwFile &&rhs)
size_t reference_antenna_
static std::string UvwAsString(const std::array< double, 3 > &uvw)
UvwFile(const std::string &filename, bool)
Open an existing file from disk.
UvwFile() noexcept=default
size_t start_antenna_2_
This value is used to determine the first baseline in the data, which is the baseline (reference_ante...
void ReadUvw(uint64_t row, size_t antenna1, size_t antenna2, double *uvw)
Read a single row.
void ActivateBlock(size_t block)
void ReadHeader(unsigned char *data)
Read an optional extra header to the file.
const std::string & Filename() const
void WriteHeader(const unsigned char *data)
Write an optional extra header to the file.
uint64_t NRows() const
Total number of rows stored in this file.
void Read(uint64_t row, uint64_t column_offset, float *data, uint64_t n)
Read one cell containing an array of floats.
void Write(uint64_t row, uint64_t column_offset, const float *data, uint64_t n)
Write one cell containing an array of floats.
void Close()
Close the file.
this file contains all the compiler specific defines
Define real & complex conjugation for non-complex types and put comparisons into std namespace.