8 #ifndef SINGLEDISH_FILLER_DATAACCUMULATOR_H_
9 #define SINGLEDISH_FILLER_DATAACCUMULATOR_H_
35 if (array.shape() !=
shape) {
36 array.resize(shape,
false);
41 inline void setValue1(ssize_t n, T
const *src, T *dst) {
42 for (ssize_t i = 0; i < n; ++i) {
51 ssize_t
const nrow = shape[0];
52 ssize_t
const ncolumn = shape[1];
53 if (icolumn >= ncolumn) {
59 T *work_p = dst_p + icolumn * nrow;
62 setValue1(nrow, src_p, work_p);
68 template<
class T,
class Executor>
69 inline void shuffleTransposeMatrix(ssize_t n,
size_t offset_src,
71 std::vector<size_t> src_order = { }) {
72 if (offset_src > src.
ncolumn() - 1)
77 T
const *wsrc_p = src_p + offset_src * n;
80 Executor::execute(n, wsrc_p, wdst_p, src_order);
86 inline void getDefaultOrder(
size_t const num_order,
87 std::vector<size_t> &order) {
88 order.resize(num_order);
89 std::iota(order.begin(), order.end(), 0);
92 inline bool setAndCheckOrder(
size_t const required_size,
size_t const max_value,
93 std::vector<size_t> &order) {
94 if (order.size() == 0)
95 getDefaultOrder(required_size, order);
97 if (order.size() < required_size) {
100 size_t max_idx = order[0];
101 for (
size_t i = 1; i < order.size(); ++i) {
102 max_idx =
std::max(max_idx, order[i]);
104 return max_idx <= max_value;
107 struct ExecuteMatrix1 {
109 static void execute(ssize_t n, T
const *src, T *dst,
110 std::vector<size_t> ) {
111 setValue1(n, src, dst);
115 struct ExecuteMatrix2 {
117 static void execute(ssize_t n, T
const *src, T *dst,
118 std::vector<size_t> src_order) {
120 if (!setAndCheckOrder(2, 3, src_order))
122 T
const *row0_p = src + src_order[0] * n;
123 T
const *row1_p = src + src_order[1] * n;
124 for (ssize_t i = 0; i < n; ++i) {
125 dst[2 * i] = row0_p[i];
126 dst[2 * i + 1] = row1_p[i];
131 struct ExecuteMatrix4X {
133 static void execute(ssize_t , T
const *, T *,
134 std::vector<size_t> ) {
135 throw std::runtime_error(
"");
141 inline void ExecuteMatrix4X::execute(ssize_t n,
casacore::Bool const *src,
143 if (!setAndCheckOrder(4, 3, src_order))
149 for (ssize_t i = 0; i < n; ++i) {
150 dst[4 * i + 0] = row0_p[i];
154 dst[4 * i + 3] = row3_p[i];
158 struct ExecuteMatrix4 {
160 static void execute(ssize_t n, T
const *src, T *dst,
161 std::vector<size_t> src_order) {
162 if (!setAndCheckOrder(4, 3, src_order))
164 T
const *row0_p = src + src_order[0] * n;
165 T
const *row1_p = src + src_order[1] * n;
166 T
const *row2_p = src + src_order[2] * n;
167 T
const *row3_p = src + src_order[3] * n;
168 for (ssize_t i = 0; i < n; ++i) {
169 dst[4 * i + 0] = row0_p[i];
170 dst[4 * i + 1] = row1_p[i];
171 dst[4 * i + 2] = row2_p[i];
172 dst[4 * i + 3] = row3_p[i];
177 inline void shuffleTransposeMatrix4F2C(ssize_t n,
180 std::vector<size_t> src_order = { }) {
181 if (!setAndCheckOrder(4, 3, src_order))
192 for (ssize_t i = 0; i < n; ++i) {
193 dst_p[4 * i].real(row0_p[i]);
194 dst_p[4 * i].imag(0.0f);
197 dst_p[4 * i + 1].real(fr);
198 dst_p[4 * i + 1].imag(fi);
199 dst_p[4 * i + 2].real(fr);
200 dst_p[4 * i + 2].imag(-fi);
201 dst_p[4 * i + 3].real(row3_p[i]);
202 dst_p[4 * i + 3].imag(0.0f);
232 std::vector<size_t> &out_idx) {
235 idx_vec.tovector(out_idx);
237 std::sort(out_idx.begin(), out_idx.end(),
238 [&in_data](
size_t const &i,
size_t const &j) ->
bool {
return in_data[i] < in_data[j];});
245 class DataAccumulator;
252 num_pol_max_(4), num_chan_(0), data_(), flag_(), flag_row_(
253 num_pol_max_, false), tsys_(), tcal_(), weight_(
254 num_pol_max_, 1.0f), sigma_(weight_), poltype_(poltype), valid_pcorr_(), pcorr_type_(), get_chunk_(
255 nullptr), get_num_pol_(nullptr) {
271 initialize(num_chan_);
276 return (*this.*get_num_pol_)();
280 num_chan_ = num_chan;
282 ::resizeTo(data_, shape);
283 ::resizeTo(flag_, shape);
284 ::resizeTo(tsys_, shape);
285 ::resizeTo(tcal_, shape);
286 pcorr_type_.resize(0);
293 pcorr_type_.resize(0);
307 if (num_pol_max_ < pcorr_type_.size()) {
312 if (num_chan_ == 0) {
313 size_t num_chan = data.
size();
314 initialize(num_chan);
320 bool consistent =
false;
321 for (
size_t i = 0; i < valid_pcorr_.size(); ++i) {
322 consistent |= (valid_pcorr_[i] == (
Int) pcorr);
326 "Got inconsistent polarization with poltype");
329 for (
size_t i = 0; i < pcorr_type_.size(); ++i) {
330 if (pcorr == pcorr_type_[i]) {
332 "DataChunk already has polarization "
337 pcorr_type_.push_back(pcorr);
339 size_t const colid = pcorr_type_.size() - 1;
365 ::setValueToMatrixColumn(data, colid, data_);
367 ::setValueToMatrixColumn(flag, colid, flag_);
368 flag_row_[colid] = flagrow;
369 if (tsys.
size() == num_chan_) {
371 ::setValueToMatrixColumn(tsys, colid, tsys_);
372 }
else if (!tsys.
empty()) {
373 tsys_(0, colid) = tsys[0];
375 if (tcal.
size() == num_chan_) {
377 ::setValueToMatrixColumn(tcal, colid, tcal_);
378 }
else if (!tcal.
empty()) {
379 tcal_(0, colid) = tcal[0];
386 bool return_value = (*this.*get_chunk_)(record);
396 return pcorr_type_.size() == 4;
399 if (pcorr_type_.size() != 2)
402 casacore::Int pcorr1 = valid_pcorr_[valid_pcorr_.size() - 1];
403 return (pcorr_type_[0] == pcorr0 && pcorr_type_[1] == pcorr1)
404 || (pcorr_type_[0] == pcorr1 && pcorr_type_[1] == pcorr0);
407 return (pcorr_type_.size() == 1
408 && valid_pcorr_[0] == (
Int) pcorr_type_[0]);
411 return (pcorr_type_.size() == 1
412 && valid_pcorr_[valid_pcorr_.size() - 1] == (
Int) pcorr_type_[0]);
421 if (poltype_ ==
"linear") {
422 get_chunk_ = &DataChunk::getLinear;
423 get_num_pol_ = &DataChunk::getNumPolLinear;
429 }
else if (poltype_ ==
"circular") {
430 get_chunk_ = &DataChunk::getCircular;
431 get_num_pol_ = &DataChunk::getNumPolCircular;
432 valid_pcorr_.resize(4);
437 }
else if (poltype_ ==
"stokes") {
438 get_chunk_ = &DataChunk::getStokes;
439 get_num_pol_ = &DataChunk::getNumPolStokes;
440 valid_pcorr_.resize(4);
445 }
else if (poltype_ ==
"linpol") {
446 get_chunk_ = &DataChunk::getLinpol;
447 get_num_pol_ = &DataChunk::getNumPolLinpol;
448 valid_pcorr_.resize(2);
476 if (!setAndCheckOrder(2, tsys_.ncolumn() - 1, order))
478 size_t apol0 = order[0], apol1 = order[order.size() - 1];
483 if (num_chan_ == 1) {
485 record.
tsys(0, 0) = tsys_(0, apol0);
486 record.
tsys(1, 0) = tsys_(0, apol1);
492 if ((tsys00 > 0.0f && tsys10 > 0.0f)
493 || (tsys01 > 0.0f && tsys11 > 0.0f)) {
495 shuffleTransposeMatrix<casacore::Float, ExecuteMatrix2>(
496 num_chan_, 0, tsys_, record.
tsys, { apol0, apol1 });
497 }
else if (tsys00 > 0.0f || tsys01 > 0.0f) {
499 record.
tsys(0, 0) = tsys_(0, apol0);
500 record.
tsys(1, 0) = tsys_(0, apol1);
506 if (!setAndCheckOrder(2, tsys_.ncolumn()-1, order))
508 size_t apol0 = order[0], apol1 = order[order.size() - 1];
513 if (num_chan_ == 1) {
515 record.
tcal(0, 0) = tcal_(0, apol0);
516 record.
tcal(1, 0) = tcal_(0, apol1);
522 if ((tcal00 > 0.0f && tcal10 > 0.0f)
523 || (tcal01 > 0.0f && tcal11 > 0.0f)) {
525 shuffleTransposeMatrix<casacore::Float, ExecuteMatrix2>(
526 num_chan_, 0, tcal_, record.
tcal, { apol0, apol1 });
527 }
else if (tcal00 > 0.0f || tcal01 > 0.0f) {
529 record.
tcal(0, 0) = tcal_(0, apol0);
530 record.
tcal(1, 0) = tcal_(0, apol1);
536 if (num_chan_ == 1) {
538 record.
tsys(0, 0) = tsys_(0, start_src);
539 }
else if (tsys_(0, start_src) > 0.0f && tsys_(1, start_src) > 0.0f) {
543 shuffleTransposeMatrix<casacore::Float, ExecuteMatrix1>(num_chan_,
544 start_src, tsys_, record.
tsys);
546 }
else if (tsys_(0, start_src) > 0.0f) {
549 record.
tsys(0, 0) = tsys_(0, start_src);
554 if (num_chan_ == 1) {
556 record.
tcal(0, 0) = tcal_(0, start_src);
557 }
else if (tcal_(0, start_src) > 0.0f && tcal_(1, start_src) > 0.0f) {
561 shuffleTransposeMatrix<casacore::Float, ExecuteMatrix1>(num_chan_,
562 start_src, tcal_, record.
tcal);
564 }
else if (tcal_(0, start_src) > 0.0f) {
567 record.
tcal(0, 0) = tcal_(0, start_src);
575 std::vector<size_t> pol_idx_order;
576 getSortIndex(col_stokes, pol_idx_order);
585 shuffleTransposeMatrix4F2C(num_chan_, data_, record.
complex_data,
587 shuffleTransposeMatrix<casacore::Bool, ExecuteMatrix4X>(num_chan_,
588 0, flag_, record.
flag, pol_idx_order);
593 setTsys2(record, pol_idx_order);
596 setTcal2(record, pol_idx_order);
599 }
else if (isDualPol()) {
604 shuffleTransposeMatrix<casacore::Float, ExecuteMatrix2>(num_chan_,
606 shuffleTransposeMatrix<casacore::Bool, ExecuteMatrix2>(num_chan_, 0,
607 flag_, record.
flag, pol_idx_order);
608 record.
flag_row = flag_row_[0] || flag_row_[1];
612 setTsys2(record, pol_idx_order);
615 setTcal2(record, pol_idx_order);
618 }
else if (isSinglePol0()) {
623 shuffleTransposeMatrix<casacore::Float, ExecuteMatrix1>(num_chan_,
625 shuffleTransposeMatrix<casacore::Bool, ExecuteMatrix1>(num_chan_, 0,
626 flag_, record.
flag, pol_idx_order);
635 }
else if (isSinglePol1()) {
640 shuffleTransposeMatrix<casacore::Float, ExecuteMatrix1>(num_chan_,
642 shuffleTransposeMatrix<casacore::Bool, ExecuteMatrix1>(num_chan_, 0,
643 flag_, record.
flag, pol_idx_order);
652 }
else if (pcorr_type_.size() == 0) {
656 throw AipsError(
"non-conforming combination of polarization accumulated");
659 record.
corr_type[i] = col_stokes[pol_idx_order[i]];
667 return getLinear(record);
674 std::vector<size_t> pol_idx_order;
675 getSortIndex(col_stokes, pol_idx_order);
680 shuffleTransposeMatrix<casacore::Float, ExecuteMatrix4>(num_chan_,
682 shuffleTransposeMatrix<casacore::Bool, ExecuteMatrix4>(num_chan_, 0,
683 flag_, record.
flag, pol_idx_order);
684 record.
flag_row = anyTrue(flag_row_);
687 }
else if (isSinglePol0()) {
689 shuffleTransposeMatrix<casacore::Float, ExecuteMatrix1>(num_chan_,
691 shuffleTransposeMatrix<casacore::Bool, ExecuteMatrix1>(num_chan_, 0,
692 flag_, record.
flag, pol_idx_order);
696 }
else if (pcorr_type_.size() == 0) {
699 throw AipsError(
"non-conforming combination of polarization accumulated");
702 record.
corr_type[i] = col_stokes[pol_idx_order[i]];
713 std::vector<size_t> pol_idx_order;
714 getSortIndex(col_stokes, pol_idx_order);
720 shuffleTransposeMatrix<casacore::Float, ExecuteMatrix2>(num_chan_,
722 shuffleTransposeMatrix<casacore::Bool, ExecuteMatrix2>(num_chan_, 0,
723 flag_, record.
flag, pol_idx_order);
724 record.
flag_row = flag_row_[0] || flag_row_[1];
726 }
else if (isSinglePol0()) {
728 shuffleTransposeMatrix<casacore::Float, ExecuteMatrix1>(num_chan_,
730 shuffleTransposeMatrix<casacore::Bool, ExecuteMatrix1>(num_chan_, 0,
731 flag_, record.
flag, pol_idx_order);
735 }
else if (pcorr_type_.size() == 0) {
738 throw AipsError(
"non-conforming combination of polarization accumulated");
741 record.
corr_type[i] = col_stokes[pol_idx_order[i]];
751 }
else if (isDualPol()) {
753 }
else if (isSinglePol0() || isSinglePol1()) {
761 return getNumPolLinear();
767 }
else if (isSinglePol0()) {
777 }
else if (isSinglePol0()) {
795 template<
class T,
class C>
796 bool comp(T
const &a, T
const &b, C
const &
c)
const {
814 []() {
return false;});});});});});});
820 pool_(), antenna_id_(), spw_id_(), field_id_(), feed_id_(), scan_(), subscan_(), intent_(), direction_(), interval_(), indexer_(), time_(
827 for (
auto iter = pool_.begin(); iter != pool_.end(); ++iter) {
839 return std::count_if(pool_.begin(), pool_.end(),
841 return c->getNumPol() > 0;
847 bool is_ready = (0.0 <= time_) && !(time_ == time);
852 bool is_ready = (0.0 <= time_) && !(time_ == time);
857 for (
auto iter = pool_.begin(); iter != pool_.end(); ++iter) {
866 if (pool_.size() == 0) {
868 }
else if (ichunk >= pool_.size()) {
871 bool status = pool_[ichunk]->get(record);
878 record.
pol_type = pool_[ichunk]->getPolType();
880 record.
spw_id = spw_id_[ichunk];
881 record.
field_id = field_id_[ichunk];
882 record.
feed_id = feed_id_[ichunk];
883 record.
scan = scan_[ichunk];
884 record.
subscan = subscan_[ichunk];
885 record.
intent = intent_[ichunk];
887 record.
interval = interval_[ichunk];
889 record.
pressure = pressure_[ichunk];
937 auto iter = indexer_.find(key);
942 if (iter != indexer_.end()) {
944 status = pool_[index]->accumulate(record);
946 antenna_id_[index] = antennaid;
947 spw_id_[index] = spwid;
948 field_id_[index] = fieldid;
949 feed_id_[index] = feedid;
951 subscan_[index] = subscan;
952 intent_[index] = intent;
953 direction_[index].
assign(direction);
954 interval_[index] = interval;
955 temperature_[index] = temperature;
956 pressure_[index] = pressure;
957 rel_humidity_[index] = rel_humidity;
958 wind_speed_[index] = wind_speed;
959 wind_direction_[index] = wind_direction;
963 antenna_id_.push_back(-1);
964 spw_id_.push_back(-1);
965 field_id_.push_back(-1);
966 feed_id_.push_back(-1);
968 subscan_.push_back(-1);
969 intent_.push_back(
"");
971 interval_.push_back(-1.0);
972 temperature_.push_back(0.0f);
973 pressure_.push_back(0.0f);
974 rel_humidity_.push_back(0.0f);
975 wind_speed_.push_back(0.0f);
976 wind_direction_.push_back(0.0f);
978 indexer_[key] = index;
979 status = pool_[index]->accumulate(record);
981 antenna_id_[index] = antennaid;
982 spw_id_[index] = spwid;
983 field_id_[index] = fieldid;
984 feed_id_[index] = feedid;
986 subscan_[index] = subscan;
987 intent_[index] = intent;
988 direction_[index].
assign(direction);
989 interval_[index] = interval;
990 temperature_[index] = temperature;
991 pressure_[index] = pressure;
992 rel_humidity_[index] = rel_humidity;
993 wind_speed_[index] = wind_speed;
994 wind_direction_[index] = wind_direction;
1008 assert(ichunk < pool_.size());
1009 return pool_[ichunk]->getPolType();
1013 assert(ichunk < pool_.size());
1014 return pool_[ichunk]->getNumPol();
1044 std::map<DataAccumulatorKey, casacore::uInt, DataAccumulatorKey>
indexer_;
A Vector of integers, for indexing into Array<T> objects.
casacore::Matrix< casacore::Float > tsys
optional
casacore::Vector< casacore::Float > sigma_
std::vector< casacore::Int > scan_
bool getStokes(MSDataRecord &record)
A 1-D Specialization of the Array class.
void setTsysSize(size_t n, size_t m)
casacore::String getPolType(size_t ichunk) const
Linearly Polarized intensity ((Q^2+U^2)^(1/2))
casacore::Vector< casacore::Int > valid_pcorr_
void putStorage(T *&storage, Bool deleteAndCopy)
putStorage() is normally called after a call to getStorage() (cf).
casacore::Double time
mandatory
std::vector< casacore::Stokes::StokesTypes > pcorr_type_
size_t const num_pol_max_
casacore::Float wind_speed
std::map< DataAccumulatorKey, casacore::uInt, DataAccumulatorKey > indexer_
size_t nelements() const
How many elements does this array have? Product of all axis lengths.
const IPosition & shape() const
The length of each axis of the Matrix.
std::complex< Float > Complex
bool accumulate(DataRecord const &record)
casacore::Float temperature
casacore::Float wind_speed
void setTcal1(MSDataRecord &record, ssize_t start_src)
void setTcal2(MSDataRecord &record, std::vector< size_t > order={})
casacore::Vector< casacore::Float > data
casacore::String pol_type
void setDataSize(size_t n, size_t m)
casacore::Vector< casacore::Float > weight_
TableExprNode array(const TableExprNode &values, const TableExprNodeSet &shape)
Create an array of the given shape and fill it with the values.
casacore::Stokes::StokesTypes pol
casacore::Float wind_direction
casacore::String pol_type
bool getCircular(MSDataRecord &record)
bool getLinear(MSDataRecord &record)
standard stokes parameters
casacore::Matrix< casacore::Float > float_data
size_type size() const
Capacity, size.
casacore::Matrix< casacore::Bool > flag
String & resize(size_type n)
Resize by truncating or extending with copies of <tt>c</tt> (default Char())
ABSTRACT TOOL CLASSES A PlotTool is a higher level event handler for a PlotCanvas The idea is to take common tasks which may require multiple events and put them in one place PlotTools also provide additional functionality in that they can be active and blocking non blocking The PlotCanvas will only send events to active and will not send events to later tools or event handlers if the latest tool was blocking In this way a single tool can be used to handle ALL user interaction via the GUI at one time
bool queryForGet(casacore::Double const &time) const
A 2-D Specialization of the Array class.
Bool empty() const
Is the array empty (i.e.
casacore::Matrix< casacore::Float > tsys_
void setTsys2(MSDataRecord &record, std::vector< size_t > order={})
Tsys and Tcal assignment for 2 & 4 pols.
casacore::Vector< casacore::Float > tsys
optional
StokesTypes
The Stokes types are defined by this enum.
bool getLinpol(MSDataRecord &record)
ABSTRACT CLASSES Deliberately vague to be general enough to allow for many different types of data
T * getStorage(Bool &deleteIt)
Generally use of this should be shunned, except to use a FORTRAN routine or something similar...
std::vector< casacore::Float > wind_direction_
std::vector< casacore::Int > feed_id_
size_t getNumberOfChunks() const
void setPolType(casacore::String const &poltype)
casacore::Vector< casacore::Bool > flag
static String name(StokesTypes stokesType)
convert StokesTypes to String, Stokes::Undefined returns "??".
void setTcalSize(size_t n, size_t m)
casacore::Vector< casacore::Int > corr_type
circular correlation products
casacore::uInt getNumPolLinear() const
virtual void assign(const Array< T > &other)
Assign the other array (which must be of dimension one) to this vector.
linear correlation products
casacore::Vector< casacore::Float > tcal
bool isValidRecord(DataRecord const &record)
casacore::Float rel_humidity
casacore::String getPolType() const
casacore::Matrix< casacore::Complex > complex_data
casacore::Double interval
casacore::Double time
mandatory
String & assign(const string &str)
Assign.
const IPosition & shape() const
The length of the Vector.
std::vector< casacore::Double > interval_
std::vector< DataChunk * > pool_
bool isValidRecord(DataRecord const &record)
std::vector< bool > is_free_
void indgen(TableVector< T > &tv, Int start, Int inc)
casacore::String poltype_
bool Bool
Define the standard types used by Casacore.
std::vector< casacore::String > intent_
std::vector< casacore::Int > field_id_
casacore::Matrix< casacore::Double > direction
bool accumulate(DataRecord const &record)
bool comp(T const &a, T const &b, C const &c) const
DataChunk(casacore::String const &poltype)
size_t ncolumn() const
The number of columns in the Matrix, i.e.
casacore::uInt getNumPolCircular() const
bool operator()(DataAccumulatorKey const &lhs, DataAccumulatorKey const &rhs) const
std::vector< casacore::Float > temperature_
void resetPolType(casacore::String const &poltype)
casacore::String pol_type
std::vector< casacore::Int > subscan_
bool isSinglePol1() const
casacore::Float temperature
TableExprNode shape(const TableExprNode &array)
Function operating on any scalar or array resulting in a Double array containing the shape...
casacore::Matrix< casacore::Float > tcal
casacore::Float wind_direction
std::vector< casacore::Matrix< casacore::Double > > direction_
void setTsys1(MSDataRecord &record, ssize_t start_src)
casacore::Matrix< casacore::Double > direction
casacore::Float rel_humidity
std::vector< casacore::Float > rel_humidity_
std::vector< casacore::Float > wind_speed_
bool isSinglePol0() const
std::vector< casacore::Int > spw_id_
casacore::Bool isValidRecord(const casacore::RecordInterface &parm, const casacore::String &id)
short inline function for checking that a field is a non-empty record
virtual ~DataAccumulator()
Base class for all Casacore library errors.
size_t getNumberOfActiveChunks() const
casacore::uInt getNumPolLinpol() const
void initialize(size_t num_chan)
const Double c
Fundamental physical constants (SI units):
casacore::uInt getNumPolStokes() const
Bool anyEQ(const TableVector< T > &l, const TableVector< T > &r)
bool isFullPol() const
Functions to return if accumulated corr types are conformant set, e.g., liner polarization should hav...
String: the storage and methods of handling collections of characters.
casacore::uInt getNumPol(size_t ichunk) const
Linear Polarization Angle (0.5 arctan(U/Q)) (in radians)
casacore::Matrix< casacore::Float > tcal_
std::vector< casacore::Float > pressure_
std::vector< casacore::Int > antenna_id_
casacore::Double interval
void freeStorage(const T *&storage, Bool deleteIt) const
If deleteIt is set, delete "storage".
casacore::Matrix< casacore::Float > data_
bool queryForGet(DataRecord const &record) const
casacore::Vector< casacore::Bool > flag_row_
casacore::uInt getNumPol() const
casacore::Matrix< casacore::Bool > flag_
#define casacore
<X11/Intrinsic.h> #defines true, false, casacore::Bool, and String.