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");
87 if (
shape.size() != 2) {
88 throw std::runtime_error(
89 "Sisco storage manager is used for a column with " +
90 std::to_string(
shape.size()) +
91 " dimensions, but it can only be used for "
92 "columns with exactly 2 dimensions");
130 if (
shape->size() >= 2) {
131 const size_t n_channels = (*shape)[1];
133 const int n_column_correlations = (*shape)[0];
139 for (
int polarization = 0; polarization != n_polarizations;
142 for (
size_t channel = 0; channel != n_channels; ++channel) {
143 storage[channel * n_polarizations + polarization] =
179 if (
array.shape().size() >= 2) {
180 const int n_column_correlations =
array.shape()[0];
183 throw std::runtime_error(
"Trying to store invalid number of correlations in Sisco column: Sisco was set to store full-correlation values as Stokes I or diagonal visibilities: can only store shape 4 values in this mode");
185 const size_t n_channels =
array.shape()[1];
190 const std::complex<float> *
storage =
array.getStorage(ownership);
194 for (
int polarization = 0; polarization != n_polarizations;
197 field_id, data_desc_id, antenna1, antenna2, polarization);
201 const size_t diagonal_index = polarization * 3;
202 for (
size_t channel = 0; channel != n_channels; ++channel) {
204 storage[channel * 4 + diagonal_index];
207 for (
size_t channel = 0; channel != n_channels; ++channel) {
209 storage[channel * n_column_correlations + polarization];
241 const bool is_reading_after_writing =
264 const std::string filename =
parent_.fileName();
284 std::string filename =
parent_.fileName();
296 uint16_t storage_mode_tag = 0;
299 storage_mode_tag = 0x8000;
302 storage_mode_tag = 0x4000;
305 storage_mode_tag = 0;
308 const uint16_t major_and_mode =
kVersionMajor | storage_mode_tag;
309 std::copy_n(
reinterpret_cast<const char *
>(&major_and_mode), 2,
311 std::copy_n(
reinterpret_cast<const char *
>(&
kVersionMinor), 2,
313 std::span<const std::byte> header(
314 reinterpret_cast<const std::byte *
>(header_buffer),
kHeaderSize);
331 std::span<std::byte> header(
reinterpret_cast<std::byte *
>(header_buffer),
335 uint16_t version_major_and_mode;
336 uint16_t version_minor;
337 std::copy_n(&header_buffer[0],
kMagicSize, magic_tag);
339 reinterpret_cast<char *
>(&version_major_and_mode));
340 std::copy_n(&header_buffer[
kMagicSize + 2], 2,
341 reinterpret_cast<char *
>(&version_minor));
342 const uint16_t version_major = version_major_and_mode & 0x3FFF;
344 throw std::runtime_error(
345 "The file on disk is written as a Sisco version " +
346 std::to_string(version_major) +
347 " file, whereas this Casacore version supports only version " +
351 const uint16_t store_mode_tag = version_major_and_mode & 0xC000;
352 if(store_mode_tag == 0) {
354 }
else if(store_mode_tag == 0x4000) {
356 }
else if(store_mode_tag == 0x8000) {
359 throw std::runtime_error(
"File specifies an unknown store mode");
367 const size_t n_requests =
reader_->GetRequestBufferSize() / 2;
378 for (
size_t i = 0; i != n_requests; ++i) {
388 if (!eof &&
shape.size() >= 2) {
390 const int data_desc_id =
395 const int n_channels =
shape[1];
396 for (
int polarization = 0; polarization != n_polarizations;
399 field_id, data_desc_id, antenna1, antenna2, polarization);
400 reader_->Request(baseline_id, n_channels);
412 int antenna2,
int polarization) {
413 const std::array<int, 5> baseline{field_id, data_desc_id, antenna1,
414 antenna2, polarization};
432 buffer_.assign(n_channels, 0.0);
437 for (
int polarization = 0; polarization != n_polarizations;
440 field_id, data_desc_id, antenna1, antenna2, polarization);
457 if (
shape->size() >= 2) {
459 const int n_channels = (*shape)[1];
462 for (
int polarization = 0; polarization != n_polarizations;
479 return n_column_correlations;
486 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.
this file contains all the compiler specific defines
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.