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,
118 assert(
file_.IsOpen());
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_) +
149 if (antenna1 != antenna2) {
152 const std::array<double, 3> ant2_uvw{uvw[0], uvw[1], uvw[2]};
156 const std::array<double, 3> ant1_uvw{-uvw[0], -uvw[1], -uvw[2]};
158 }
else if (
IsSet(antenna1)) {
161 const std::array<double, 3> ant1_uvw =
block_uvws_[antenna1];
162 const std::array<double, 3> ant2_uvw{
163 uvw[0] + ant1_uvw[0], uvw[1] + ant1_uvw[1], uvw[2] + ant1_uvw[2]};
165 }
else if (
IsSet(antenna2)) {
168 const std::array<double, 3> ant2_uvw =
block_uvws_[antenna2];
169 const std::array<double, 3> ant1_uvw{
170 ant2_uvw[0] - uvw[0], ant2_uvw[1] - uvw[1], ant2_uvw[2] - uvw[2]};
173 throw std::runtime_error(
174 "Baselines are written in a non-ordered way: they need to be "
175 "ordered either by antenna 1 or by antenna 2");
196 void ReadUvw(uint64_t row,
size_t antenna1,
size_t antenna2,
double* uvw) {
197 assert(
file_.IsOpen());
199 throw std::runtime_error(
200 "Invalid read for Uvw data: row " + std::to_string(row) +
201 ", baseline (" + std::to_string(antenna1) +
", " +
202 std::to_string(antenna2) +
") was requested. File has only " +
203 std::to_string(
n_rows_) +
" rows with " +
216 if (
file_.IsOpen()) {
250 sizeof(double) * 3)) {}
262 throw std::runtime_error(
263 "Uvw file has an incorrect number of rows (" +
264 std::to_string(
file_.NRows()) +
", expecting multiple of " +
265 std::to_string(
n_antennas_ - 1) +
"): file corrupted?");
273 throw std::runtime_error(
274 "Invalid combination of values for n_antenna and reference antenna "
275 "in file: file damaged?");
288 void StoreOrCheck(
size_t antenna,
const std::array<double, 3>& antenna_uvw) {
289 if (
IsSet(antenna)) {
291 std::ostringstream msg;
292 msg <<
"Inconsistent UVW value written for antenna " << antenna
294 <<
", new value is " <<
UvwAsString(antenna_uvw) <<
".";
295 throw std::runtime_error(msg.str());
318 if (block_start_row <
file_.NRows()) {
320 for (
size_t antenna = 0; antenna !=
n_antennas_; ++antenna) {
323 ? block_start_row + antenna
324 : block_start_row + antenna - 1;
325 std::array<double, 3>& uvw =
block_uvws_.emplace_back();
326 file_.Read(row, 0, uvw.data(), 3);
328 block_uvws_.emplace_back(std::array<double, 3>{0.0, 0.0, 0.0});
339 throw std::runtime_error(
"Trying to write an incomplete UVW block");
341 for (
size_t antenna = 0; antenna !=
n_antennas_; ++antenna) {
344 ? block_start_row + antenna
345 : block_start_row + antenna - 1;
354 file_.ReadHeader(data);
356 throw std::runtime_error(
357 "The UVW columnar file header not have the expected tag for UVW "
358 "columns: the measurement set may be damaged");
362 n_antennas_ =
reinterpret_cast<uint64_t&
>(data[24]);
370 reinterpret_cast<uint64_t&
>(data[24]) =
n_antennas_;
371 file_.WriteHeader(data);
378 static bool AreNear(std::array<double, 3> a, std::array<double, 3> b) {
382 const double magnitude = std::max({1e-5, std::fabs(a), std::fabs(b)});
383 return (std::fabs(a - b) / magnitude) < 1e-5;
385 static std::string
UvwAsString(
const std::array<double, 3>& uvw) {
386 std::ostringstream str;
387 str <<
"[" << uvw[0] <<
", " << uvw[1] <<
", " << uvw[2] <<
"]";
401 std::numeric_limits<double>::max(), std::numeric_limits<double>::max(),
402 std::numeric_limits<double>::max()};
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)
this file contains all the compiler specific defines
void move(TYPE *target, int npixels) const
VarBufferedColumnarFile< 100 *1024 > BufferedColumnarFile
Define real & complex conjugation for non-complex types and put comparisons into std namespace.