1#ifndef CASACORE_SISCO_ST_MAN_COLUMN_H_
2#define CASACORE_SISCO_ST_MAN_COLUMN_H_
4#include <casacore/tables/DataMan/StManColumn.h>
6#include <casacore/casa/Arrays/Array.h>
7#include <casacore/casa/Arrays/IPosition.h>
9#include <casacore/tables/Tables/ScalarColumn.h>
10#include <casacore/tables/AlternateMans/StokesIConversions.h>
51 if (
dtype != casacore::TpComplex) {
52 throw std::runtime_error(
53 "Sisco storage manager column can only be used for a data column "
54 "with single precision complex values");
85 if (
shape.size() != 2) {
86 throw std::runtime_error(
"Sisco storage manager is used for a column with " +
87 std::to_string(
shape.size()) +
88 " dimensions, but it can only be used for "
89 "columns with exactly 2 dimensions");
124 if (
shape->size() >= 2) {
125 const size_t n_channels = (*shape)[1];
127 const int n_column_correlations = (*shape)[0];
133 for (
int polarization = 0; polarization != n_polarizations; ++polarization) {
135 for (
size_t channel = 0; channel != n_channels; ++channel) {
136 storage[channel * n_polarizations + polarization] =
buffer_[channel];
171 if (
array.shape().size() >= 2) {
172 const int n_column_correlations =
array.shape()[0];
174 n_column_correlations != 4) {
175 throw std::runtime_error(
176 "Trying to store invalid number of correlations in Sisco column: Sisco was set to "
177 "store full-correlation values as Stokes I or diagonal visibilities: can only store "
178 "shape 4 values in this mode");
180 const size_t n_channels =
array.shape()[1];
185 const std::complex<float> *
storage =
array.getStorage(ownership);
188 for (
int polarization = 0; polarization != n_polarizations; ++polarization) {
189 const size_t baseline_id =
190 GetBaselineId(field_id, data_desc_id, antenna1, antenna2, polarization);
194 const size_t diagonal_index = polarization * 3;
195 for (
size_t channel = 0; channel != n_channels; ++channel) {
199 for (
size_t channel = 0; channel != n_channels; ++channel) {
200 buffer_[channel] =
storage[channel * n_column_correlations + polarization];
232 const bool is_reading_after_writing =
255 const std::string filename =
parent_.fileName();
274 std::string filename =
parent_.fileName();
286 uint16_t storage_mode_tag = 0;
289 storage_mode_tag = 0x8000;
292 storage_mode_tag = 0x4000;
295 storage_mode_tag = 0;
298 const uint16_t major_and_mode =
kVersionMajor | storage_mode_tag;
299 std::copy_n(
reinterpret_cast<const char *
>(&major_and_mode), 2, &header_buffer[
kMagicSize]);
301 std::span<const std::byte> header(
reinterpret_cast<const std::byte *
>(header_buffer),
319 std::span<std::byte> header(
reinterpret_cast<std::byte *
>(header_buffer),
kHeaderSize);
322 uint16_t version_major_and_mode;
323 uint16_t version_minor;
324 std::copy_n(&header_buffer[0],
kMagicSize, magic_tag);
325 std::copy_n(&header_buffer[
kMagicSize], 2,
reinterpret_cast<char *
>(&version_major_and_mode));
326 std::copy_n(&header_buffer[
kMagicSize + 2], 2,
reinterpret_cast<char *
>(&version_minor));
327 const uint16_t version_major = version_major_and_mode & 0x3FFF;
329 throw std::runtime_error(
"The file on disk is written as a Sisco version " +
330 std::to_string(version_major) +
331 " file, whereas this Casacore version supports only version " +
335 const uint16_t store_mode_tag = version_major_and_mode & 0xC000;
336 if (store_mode_tag == 0) {
338 }
else if (store_mode_tag == 0x4000) {
340 }
else if (store_mode_tag == 0x8000) {
343 throw std::runtime_error(
"File specifies an unknown store mode");
351 const size_t n_requests =
reader_->GetRequestBufferSize() / 2;
362 for (
size_t i = 0; i != n_requests; ++i) {
371 if (!eof &&
shape.size() >= 2) {
377 const int n_channels =
shape[1];
378 for (
int polarization = 0; polarization != n_polarizations; ++polarization) {
379 const size_t baseline_id =
380 GetBaselineId(field_id, data_desc_id, antenna1, antenna2, polarization);
381 reader_->Request(baseline_id, n_channels);
391 size_t GetBaselineId(
int field_id,
int data_desc_id,
int antenna1,
int antenna2,
393 const std::array<int, 5> baseline{field_id, data_desc_id, antenna1, antenna2, polarization};
408 buffer_.assign(n_channels, 0.0);
413 for (
int polarization = 0; polarization != n_polarizations; ++polarization) {
414 const size_t baseline_id =
415 GetBaselineId(field_id, data_desc_id, antenna1, antenna2, polarization);
432 if (
shape->size() >= 2) {
434 const int n_channels = (*shape)[1];
437 for (
int polarization = 0; polarization != n_polarizations; ++polarization) {
453 return n_column_correlations;
460 static constexpr char kMagic[] =
"Sisco\0\0\0";
Non-templated base class for templated Array class.
Bool isFixedShape() const
Is this a fixed shape column?
static constexpr uint16_t kVersionMinor
std::optional< ShapesFileWriter > shapes_writer_
static constexpr char kMagic[]
rownr_t current_read_row_
std::vector< IPosition > shape_buffer_
A circular buffer to store the already read shapes.
std::optional< sisco::SiscoReader > reader_
size_t shape_write_position_
When reading a new shape from file, this is the place inside the shape buffer to write it to.
void setShapeColumn(const IPosition &shape) final
Set the dimensions of values in this column.
void putArrayV(rownr_t row, const ArrayBase &dataPtr) final
Write values into a particular row.
IPosition shape(unsigned row) final
bool canChangeShape() const final
Can the data manager handle chaging the shape of an existing array?
void PrepareReadingOfRow(rownr_t row)
static constexpr size_t kMagicSize
IPosition shape(rownr_t row) final
Get the dimensions of the values in a particular row.
static constexpr char kTemporaryExtension[]
std::optional< ShapesFileReader > shapes_reader_
bool isShapeDefined(rownr_t) final
Is the value shape defined in the given row?
bool isWritable() const final
Whether this column is writable.
constexpr int GetNStoredCorrelations(const size_t n_column_correlations) const
std::map< std::array< int, 5 >, size_t > baseline_ids_
SiscoStManColumn(const SiscoStManColumn &source)=delete
ScalarColumn< int > antenna2_column_
void operator=(const SiscoStManColumn &source)=delete
SiscoStManColumn(SiscoStMan &parent, DataType dtype, SiscoStoreMode mode)
SiscoStoreMode store_mode_
rownr_t row_count_
When reading, this value is set to the number of rows in the measurement set.
bool isShapeDefined(unsigned row) final
void setShape(rownr_t, const IPosition &) final
Set the shape of an (variable-shaped) array in the given row.
void setShape(unsigned, const IPosition &) final
size_t shape_read_position_
Points inside shape_buffer_ to the location corresponding to the shape for the current_read_row_.
rownr_t current_write_row_
bool has_temporary_file_
If true, writing is done to a temporary file such that reading can still take place from the old file...
size_t GetBaselineId(int field_id, int data_desc_id, int antenna1, int antenna2, int polarization)
void getArrayV(rownr_t row, ArrayBase &dataPtr) final
Read the values for a particular row.
ScalarColumn< int > data_desc_id_column_
static constexpr uint16_t kVersionMajor
static constexpr char kShapesExtension[]
ScalarColumn< int > antenna1_column_
~SiscoStManColumn() override
ScalarColumn< int > field_id_column_
std::optional< sisco::SiscoWriter > writer_
rownr_t current_requested_reading_row_
std::string ShapesFilename() const
static constexpr size_t kHeaderSize
std::vector< std::complex< float > > buffer_
Scratch buffer.
The Stokes I storage manager behaves like a full set of (4) polarizations but only stores the Stokes ...
StManColumn(int dataType)
Default constructor.
For temporary backward namespace compatibility, use casa as alias for casacore.
void ExpandFromDiagonal(T *data, size_t n)
Performs in-place expansion of n pair of diagonal values such that each pair becomes 4 values with ze...
T * array
The actual storage.
T * storage()
If you really, really, need a "raw" pointer to the beginning of the storage area this will give it to...
T * TransformToStokesI(const T *input, T *buffer, size_t n)
Calculates for every set of 4 input values the Stokes-I values by doing out = 0.5 * (in_pp + in_qq),...
void CheckIsDiagonal(const T *input, size_t n)
Check if every set of 4 input values contains only non-zeros on the diagonal (pp or qq).
void ExpandFromStokesI(T *data, size_t n)
Expands n values from single Stokes I values to have 4 values, in place.
uInt64 rownr_t
Define the type of a row number in a table.