casa  5.7.0-16
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
DataAccumulator.h
Go to the documentation of this file.
1 /*
2  * DataAccumulator.h
3  *
4  * Created on: Jan 18, 2016
5  * Author: nakazato
6  */
7 
8 #ifndef SINGLEDISH_FILLER_DATAACCUMULATOR_H_
9 #define SINGLEDISH_FILLER_DATAACCUMULATOR_H_
10 
11 #include <vector>
12 #include <cassert>
13 #include <memory>
14 #include <algorithm>
15 #include <numeric>
16 
23 
25 
29 
30 using namespace casacore;
31 
32 namespace {
33 template<class T>
34 inline void resizeTo(T &array, casacore::IPosition const &shape) {
35  if (array.shape() != shape) {
36  array.resize(shape, false);
37  }
38 }
39 
40 template<class T>
41 inline void setValue1(ssize_t n, T const *src, T *dst) {
42  for (ssize_t i = 0; i < n; ++i) {
43  dst[i] = src[i];
44  }
45 }
46 
47 template<class T>
48 inline void setValueToMatrixColumn(casacore::Vector<T> const &src,
49  ssize_t icolumn, casacore::Matrix<T> &dst) {
50  casacore::IPosition const &shape = dst.shape();
51  ssize_t const nrow = shape[0];
52  ssize_t const ncolumn = shape[1];
53  if (icolumn >= ncolumn) {
54  throw casacore::AipsError("Specified column doesn't exist.");
55  }
56 
57  casacore::Bool b1, b2;
58  T *dst_p = dst.getStorage(b1);
59  T *work_p = dst_p + icolumn * nrow;
60  T const *src_p = src.getStorage(b2);
61 
62  setValue1(nrow, src_p, work_p);
63 
64  src.freeStorage(src_p, b2);
65  dst.putStorage(dst_p, b1);
66 }
67 
68 template<class T, class Executor>
69 inline void shuffleTransposeMatrix(ssize_t n, size_t offset_src,
70  casacore::Matrix<T> const &src, casacore::Matrix<T> &dst,
71  std::vector<size_t> src_order = { }) {
72  if (offset_src > src.ncolumn() - 1)
73  throw casacore::AipsError("offset too large");
74  casacore::Bool b1, b2;
75  T const *src_p = src.getStorage(b1);
76  T *dst_p = dst.getStorage(b2);
77  T const *wsrc_p = src_p + offset_src * n;
78  T *wdst_p = dst_p;
79 
80  Executor::execute(n, wsrc_p, wdst_p, src_order);
81 
82  src.freeStorage(src_p, b1);
83  dst.putStorage(dst_p, b2);
84 }
85 
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);
90 }
91 
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);
96 
97  if (order.size() < required_size) {
98  return false;
99  }
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]);
103  }
104  return max_idx <= max_value;
105 }
106 
107 struct ExecuteMatrix1 {
108  template<class T>
109  static void execute(ssize_t n, T const *src, T *dst,
110  std::vector<size_t> /*in_order*/) {
111  setValue1(n, src, dst);
112  }
113 };
114 
115 struct ExecuteMatrix2 {
116  template<class T>
117  static void execute(ssize_t n, T const *src, T *dst,
118  std::vector<size_t> src_order) {
119  // need to set max_value=3 for 4 pol case
120  if (!setAndCheckOrder(2, 3, src_order))
121  throw casacore::AipsError("got invalid order list");
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];
127  }
128  }
129 };
130 
131 struct ExecuteMatrix4X {
132  template<class T>
133  static void execute(ssize_t /*n*/, T const */*src*/, T */*dst*/,
134  std::vector<size_t> /*in_order*/) {
135  throw std::runtime_error("");
136  }
137 };
138 
139 // polarization order assumption (auto, cross, cross, auto)
140 template<>
141 inline void ExecuteMatrix4X::execute(ssize_t n, casacore::Bool const *src,
142  casacore::Bool *dst, std::vector<size_t> src_order) {
143  if (!setAndCheckOrder(4, 3, src_order))
144  throw casacore::AipsError("got invalid order list");
145  casacore::Bool const *row0_p = src + src_order[0] * n;
146  casacore::Bool const *row1_p = src + src_order[1] * n;
147  casacore::Bool const *row2_p = src + src_order[2] * n;
148  casacore::Bool const *row3_p = src + src_order[3] * n;
149  for (ssize_t i = 0; i < n; ++i) {
150  dst[4 * i + 0] = row0_p[i];
151  casacore::Bool b = row1_p[i] || row2_p[i];
152  dst[4 * i + 1] = b;
153  dst[4 * i + 2] = b;
154  dst[4 * i + 3] = row3_p[i];
155  }
156 }
157 
158 struct ExecuteMatrix4 {
159  template<class T>
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))
163  throw casacore::AipsError("got invalid order list");
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];
173  }
174  }
175 };
176 
177 inline void shuffleTransposeMatrix4F2C(ssize_t n,
180  std::vector<size_t> src_order = { }) {
181  if (!setAndCheckOrder(4, 3, src_order))
182  throw casacore::AipsError("got invalid order list");
183  casacore::Bool b1, b2;
184  casacore::Float const *src_p = src.getStorage(b1);
185  casacore::Complex *dst_p = dst.getStorage(b2);
186 
187  // polarization order assumption (auto, cross, cross, auto)
188  casacore::Float const *row0_p = src_p + src_order[0] * n;
189  casacore::Float const *row1_p = src_p + src_order[1] * n;
190  casacore::Float const *row2_p = src_p + src_order[2] * n;
191  casacore::Float const *row3_p = src_p + src_order[3] * n;
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);
195  casacore::Float fr = row1_p[i];
196  casacore::Float fi = row2_p[i];
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);
203  }
204 
205  src.freeStorage(src_p, b1);
206  dst.putStorage(dst_p, b2);
207 }
208 
210 //template<class T>
211 //inline void suffleMatrixColumn(casacore::Matrix<T> const &src,
212 // std::vector<size_t> order) {
213 // ssize_t n = src.nrow();
214 // if (checkOrder(1, src.ncolumn()-1, order)) throw AipsError("Invalid order");
215 // casacore::Matrix<T> const temp = src;
216 // casacore::Bool b1, b2;
217 // T const *src_p = src.getStorage(b1);
218 // T const *temp_p = temp.getStorage(b2);
219 // if (src_p==temp_p) {
220 // throw casacore::AipsError("Failed to generate temp storage");
221 // }
222 // for (ssize_t j = 0; j < order.size(); ++j) {
223 // setValue1(n, temp_p[order[j]*n], src_p[j*n]);
224 // }
225 // src.putStorage(src_p, b1);
226 // temp.freeStorage(temp_p, b2);
227 //}
228 
229 // get a vector of indices (out_idx) to sort in_data in accending order
230 template<typename T>
231 inline void getSortIndex(casacore::Vector<T> in_data,
232  std::vector<size_t> &out_idx) {
233  casacore::Vector<size_t> idx_vec(in_data.size());
234  casacore::indgen(idx_vec);
235  idx_vec.tovector(out_idx);
236 
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];});
239 }
240 }
241 
242 namespace casa { //# NAMESPACE CASA - BEGIN
243 namespace sdfiller { //# NAMESPACE SDFILLER - BEGIN
244 
245 class DataAccumulator;
246 
247 class DataChunk {
248 public:
250 
251  DataChunk(casacore::String const &poltype) :
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) {
256  POST_START;
257 
258  setPolType(poltype);
259 
260  POST_END;
261  }
262 
263  virtual ~DataChunk() {
264  }
265 
267  return poltype_;
268  }
269 
270  void resetPolType(casacore::String const &poltype) {
271  initialize(num_chan_);
272  setPolType(poltype);
273  }
274 
276  return (*this.*get_num_pol_)();
277  }
278 
279  void initialize(size_t num_chan) {
280  num_chan_ = num_chan;
281  casacore::IPosition const shape(2, num_chan_, num_pol_max_);
282  ::resizeTo(data_, shape);
283  ::resizeTo(flag_, shape);
284  ::resizeTo(tsys_, shape);
285  ::resizeTo(tcal_, shape);
286  pcorr_type_.resize(0);
287  tsys_ = -1.0f;
288  tcal_ = -1.0f;
289  }
290 
291  void clear() {
292  num_chan_ = 0;
293  pcorr_type_.resize(0);
294  }
295 
296  bool readyToWrite() {
297  return true;
298  }
299 
300  bool accumulate(DataRecord const &record) {
301  POST_START;
302 
303  if (!isValidRecord(record)) {
304  return false;
305  }
306 
307  if (num_pol_max_ < pcorr_type_.size()) {
308  return false;
309  }
310 
312  if (num_chan_ == 0) {
313  size_t num_chan = data.size();
314  initialize(num_chan);
315  }
316 
317  // Polarization
318  casacore::Stokes::StokesTypes pcorr = record.pol;
319  // check for consistency between pol_type and stokes
320  bool consistent = false;
321  for (size_t i = 0; i < valid_pcorr_.size(); ++i) {
322  consistent |= (valid_pcorr_[i] == (Int) pcorr);
323  }
324  if (!consistent) {
325  throw casacore::AipsError(
326  "Got inconsistent polarization with poltype");
327  }
328  // check if pcorr is the new corr type to be added
329  for (size_t i = 0; i < pcorr_type_.size(); ++i) {
330  if (pcorr == pcorr_type_[i]) {
331  throw casacore::AipsError(
332  "DataChunk already has polarization "
333  + casacore::Stokes::name(pcorr));
334  }
335  }
336  // new polarization type
337  pcorr_type_.push_back(pcorr);
338  // Matrices in DataRecord is stacked in the order of accumulation
339  size_t const colid = pcorr_type_.size() - 1;
340 
341  casacore::Vector<casacore::Bool> const &flag = record.flag;
342  casacore::Bool flagrow = record.flag_row;
343 
344  if (data.shape() != flag.shape()) {
345  return false;
346  }
347 
349  if (!record.tsys.empty()) {
350 // std::cout << "tsys is not empty: " << record.tsys[0] << std::endl;
351  tsys.assign(record.tsys);
352  }
354  if (!record.tcal.empty()) {
355 // std::cout << "tcal is not empty: " << record.tcal << std::endl;
356  tcal.assign(record.tcal);
357  }
358 
359  if (data.nelements() != num_chan_) {
360  return false;
361  }
362 
363  // Filling Matrices[chan, pol] in DataRecord. The Matrices are column (channel) major
364  //data_.column(colid) = data;
365  ::setValueToMatrixColumn(data, colid, data_);
366  //flag_.column(colid) = flag;
367  ::setValueToMatrixColumn(flag, colid, flag_);
368  flag_row_[colid] = flagrow;
369  if (tsys.size() == num_chan_) {
370  //tsys_.column(polid) = tsys;
371  ::setValueToMatrixColumn(tsys, colid, tsys_);
372  } else if (!tsys.empty()) {
373  tsys_(0, colid) = tsys[0];
374  }
375  if (tcal.size() == num_chan_) {
376  //tcal_.column(polid) = tcal;
377  ::setValueToMatrixColumn(tcal, colid, tcal_);
378  } else if (!tcal.empty()) {
379  tcal_(0, colid) = tcal[0];
380  }
381 
382  return true;
383  }
384 
385  bool get(MSDataRecord &record) {
386  bool return_value = (*this.*get_chunk_)(record);
387  return return_value;
388  }
389 
390 private:
391  // Functions to return if accumulated corr types are conformant set, e.g.,
392  // liner polarization should have XX and YY for dual pol.
393  // assumption: pcorr_type_ has StokesTypes consistent with poltype_ and
394  // not redundant (assured by accumulate())
395  bool isFullPol() const {
396  return pcorr_type_.size() == 4;
397  }
398  bool isDualPol() const {
399  if (pcorr_type_.size() != 2)
400  return false;
401  casacore::Int pcorr0 = valid_pcorr_[0];
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);
405  }
406  bool isSinglePol0() const {
407  return (pcorr_type_.size() == 1
408  && valid_pcorr_[0] == (Int) pcorr_type_[0]);
409  }
410  bool isSinglePol1() const {
411  return (pcorr_type_.size() == 1
412  && valid_pcorr_[valid_pcorr_.size() - 1] == (Int) pcorr_type_[0]);
413  }
414  bool isValidRecord(DataRecord const &record) {
415  return !record.data.empty() && !record.flag.empty();
416  }
417  void setPolType(casacore::String const &poltype) {
418  POST_START;
419 
420  poltype_ = poltype;
421  if (poltype_ == "linear") {
422  get_chunk_ = &DataChunk::getLinear;
423  get_num_pol_ = &DataChunk::getNumPolLinear;
424  valid_pcorr_.resize(4);
425  valid_pcorr_[0] = casacore::Stokes::XX;
426  valid_pcorr_[1] = casacore::Stokes::XY;
427  valid_pcorr_[2] = casacore::Stokes::YX;
428  valid_pcorr_[3] = casacore::Stokes::YY;
429  } else if (poltype_ == "circular") {
430  get_chunk_ = &DataChunk::getCircular;
431  get_num_pol_ = &DataChunk::getNumPolCircular;
432  valid_pcorr_.resize(4);
433  valid_pcorr_[0] = casacore::Stokes::RR;
434  valid_pcorr_[1] = casacore::Stokes::RL;
435  valid_pcorr_[2] = casacore::Stokes::LR;
436  valid_pcorr_[3] = casacore::Stokes::LL;
437  } else if (poltype_ == "stokes") {
438  get_chunk_ = &DataChunk::getStokes;
439  get_num_pol_ = &DataChunk::getNumPolStokes;
440  valid_pcorr_.resize(4);
441  valid_pcorr_[0] = casacore::Stokes::I;
442  valid_pcorr_[1] = casacore::Stokes::Q;
443  valid_pcorr_[2] = casacore::Stokes::U;
444  valid_pcorr_[3] = casacore::Stokes::V;
445  } else if (poltype_ == "linpol") {
446  get_chunk_ = &DataChunk::getLinpol;
447  get_num_pol_ = &DataChunk::getNumPolLinpol;
448  valid_pcorr_.resize(2);
449  valid_pcorr_[0] = casacore::Stokes::Plinear;
450  valid_pcorr_[1] = casacore::Stokes::Pangle;
451  } else {
452  throw casacore::AipsError(
453  casacore::String("Invalid poltype") + poltype);
454  }
455 
456  POST_END;
457  }
458  size_t const num_pol_max_;
459  size_t num_chan_;
467 
470  std::vector<casacore::Stokes::StokesTypes> pcorr_type_;
471  bool (DataChunk::*get_chunk_)(MSDataRecord &record);
472  casacore::uInt (DataChunk::*get_num_pol_)() const;
473 
474  // Tsys and Tcal assignment for 2 & 4 pols. Auto-correlation components of pol should be used.
475  void setTsys2(MSDataRecord &record, std::vector<size_t> order = { }) {
476  if (!setAndCheckOrder(2, tsys_.ncolumn() - 1, order))
477  throw casacore::AipsError("got invalid order list");
478  size_t apol0 = order[0], apol1 = order[order.size() - 1];
479 
480  // clear Tsys
481  record.setTsysSize(0, 0);
482 
483  if (num_chan_ == 1) {
484  record.setTsysSize(2, 1);
485  record.tsys(0, 0) = tsys_(0, apol0);
486  record.tsys(1, 0) = tsys_(0, apol1);
487  } else {
488  casacore::Float tsys00 = tsys_(0, apol0);
489  casacore::Float tsys01 = tsys_(0, apol1);
490  casacore::Float tsys10 = tsys_(1, apol0);
491  casacore::Float tsys11 = tsys_(1, apol1);
492  if ((tsys00 > 0.0f && tsys10 > 0.0f)
493  || (tsys01 > 0.0f && tsys11 > 0.0f)) {
494  record.setTsysSize(2, num_chan_);
495  shuffleTransposeMatrix<casacore::Float, ExecuteMatrix2>(
496  num_chan_, 0, tsys_, record.tsys, { apol0, apol1 });
497  } else if (tsys00 > 0.0f || tsys01 > 0.0f) {
498  record.setTsysSize(2, 1);
499  record.tsys(0, 0) = tsys_(0, apol0);
500  record.tsys(1, 0) = tsys_(0, apol1);
501  }
502  }
503  }
504 
505  void setTcal2(MSDataRecord &record, std::vector<size_t> order = { }) {
506  if (!setAndCheckOrder(2, tsys_.ncolumn()-1, order))
507  throw casacore::AipsError("got invalid order list");
508  size_t apol0 = order[0], apol1 = order[order.size() - 1];
509 
510  // clear Tcal
511  record.setTcalSize(0, 0);
512 
513  if (num_chan_ == 1) {
514  record.setTcalSize(2, 1);
515  record.tcal(0, 0) = tcal_(0, apol0);
516  record.tcal(1, 0) = tcal_(0, apol1);
517  } else {
518  casacore::Float tcal00 = tcal_(0, apol0);
519  casacore::Float tcal01 = tcal_(0, apol1);
520  casacore::Float tcal10 = tcal_(1, apol0);
521  casacore::Float tcal11 = tcal_(1, apol1);
522  if ((tcal00 > 0.0f && tcal10 > 0.0f)
523  || (tcal01 > 0.0f && tcal11 > 0.0f)) {
524  record.setTcalSize(2, num_chan_);
525  shuffleTransposeMatrix<casacore::Float, ExecuteMatrix2>(
526  num_chan_, 0, tcal_, record.tcal, { apol0, apol1 });
527  } else if (tcal00 > 0.0f || tcal01 > 0.0f) {
528  record.setTcalSize(2, 1);
529  record.tcal(0, 0) = tcal_(0, apol0);
530  record.tcal(1, 0) = tcal_(0, apol1);
531  }
532  }
533  }
534 
535  void setTsys1(MSDataRecord &record, ssize_t start_src) {
536  if (num_chan_ == 1) {
537  record.setTsysSize(1, 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) {
540  // should be spectral Tsys
541  record.setTsysSize(1, num_chan_);
542  //record.tsys = -1;
543  shuffleTransposeMatrix<casacore::Float, ExecuteMatrix1>(num_chan_,
544  start_src, tsys_, record.tsys);
545  //record.tsys.row(0) = tsys_.column(0);
546  } else if (tsys_(0, start_src) > 0.0f) {
547  // scalar Tsys
548  record.setTsysSize(1, 1);
549  record.tsys(0, 0) = tsys_(0, start_src);
550  }
551  }
552 
553  void setTcal1(MSDataRecord &record, ssize_t start_src) {
554  if (num_chan_ == 1) {
555  record.setTcalSize(1, 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) {
558  // should be spectral Tsys
559  record.setTcalSize(1, num_chan_);
560  //record.tsys = -1;
561  shuffleTransposeMatrix<casacore::Float, ExecuteMatrix1>(num_chan_,
562  start_src, tcal_, record.tcal);
563  //record.tsys.row(0) = tsys_.column(0);
564  } else if (tcal_(0, start_src) > 0.0f) {
565  // scalar Tsys
566  record.setTcalSize(1, 1);
567  record.tcal(0, 0) = tcal_(0, start_src);
568  }
569  }
570 
571  bool getLinear(MSDataRecord &record) {
572  POST_START;
573 
574  casacore::Vector<casacore::Int> const col_stokes(pcorr_type_);
575  std::vector<size_t> pol_idx_order;
576  getSortIndex(col_stokes, pol_idx_order);
577 
580  if (isFullPol()) {
581  // POL 0, 1, 2, and 3
582 // std::cout << "set data/flag" << std::endl;
583  record.setComplex();
584  record.setDataSize(4, num_chan_);
585  shuffleTransposeMatrix4F2C(num_chan_, data_, record.complex_data,
586  pol_idx_order);
587  shuffleTransposeMatrix<casacore::Bool, ExecuteMatrix4X>(num_chan_,
588  0, flag_, record.flag, pol_idx_order);
589  record.flag_row = anyEQ(flag_row_, true);
590 // std::cout << "weight = " << record.weight << std::endl;
591 
592 // std::cout << "set tsys" << std::endl;
593  setTsys2(record, pol_idx_order);
594 
595 // std::cout << "set tcal " << tcal_ << std::endl;
596  setTcal2(record, pol_idx_order);
597 
598  record.num_pol = 4;
599  } else if (isDualPol()) {
600  // POL 0 and 1
601 // std::cout << "set data/flag" << std::endl;
602  record.setFloat();
603  record.setDataSize(2, num_chan_);
604  shuffleTransposeMatrix<casacore::Float, ExecuteMatrix2>(num_chan_,
605  0, data_, record.float_data, pol_idx_order);
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];
609 // std::cout << "weight = " << record.weight << std::endl;
610 
611 // std::cout << "set tsys" << std::endl;
612  setTsys2(record, pol_idx_order);
613 
614 // std::cout << "set tcal " << tcal_ << std::endl;
615  setTcal2(record, pol_idx_order);
616 
617  record.num_pol = 2;
618  } else if (isSinglePol0()) {
619  // only POL 0
620 // std::cout << "set data/flag (pol 0)" << std::endl;
621  record.setFloat();
622  record.setDataSize(1, num_chan_);
623  shuffleTransposeMatrix<casacore::Float, ExecuteMatrix1>(num_chan_,
624  0, data_, record.float_data, pol_idx_order);
625  shuffleTransposeMatrix<casacore::Bool, ExecuteMatrix1>(num_chan_, 0,
626  flag_, record.flag, pol_idx_order);
627  record.flag_row = flag_row_(0);
628 
629  setTsys1(record, 0);
630 
631 // std::cout << "set tcal " << tcal_ << std::endl;
632  setTcal1(record, 0);
633 
634  record.num_pol = 1;
635  } else if (isSinglePol1()) {
636  // only POL 1
637 // std::cout << "set data/flag (pol 1)" << std::endl;
638  record.setFloat();
639  record.setDataSize(1, num_chan_);
640  shuffleTransposeMatrix<casacore::Float, ExecuteMatrix1>(num_chan_,
641  0, data_, record.float_data, pol_idx_order);
642  shuffleTransposeMatrix<casacore::Bool, ExecuteMatrix1>(num_chan_, 0,
643  flag_, record.flag, pol_idx_order);
644  record.flag_row = flag_row_(1);
645 
646  setTsys1(record, 0);
647 
648 // std::cout << "set tcal " << tcal_ << std::endl;
649  setTcal1(record, 0);
650 
651  record.num_pol = 1;
652  } else if (pcorr_type_.size() == 0) {
653 // std::cout << "DataChunk is not ready for get" << std::endl;
654  return false;
655  } else {// means strange combination of polarization types in DataChunk
656  throw AipsError("non-conforming combination of polarization accumulated");
657  }
658  for (casacore::Int i = 0; i < record.num_pol; ++i) {
659  record.corr_type[i] = col_stokes[pol_idx_order[i]];
660  }
661 
662  POST_END;
663  return true;
664  }
665 
666  bool getCircular(MSDataRecord &record) {
667  return getLinear(record);
668  }
669 
670  bool getStokes(MSDataRecord &record) {
671  POST_START;
672 
673  casacore::Vector<casacore::Int> const col_stokes(pcorr_type_);
674  std::vector<size_t> pol_idx_order;
675  getSortIndex(col_stokes, pol_idx_order);
676 
677  record.setFloat();
678  if (isFullPol()) {
679  record.setDataSize(4, num_chan_);
680  shuffleTransposeMatrix<casacore::Float, ExecuteMatrix4>(num_chan_,
681  0, data_, record.float_data, pol_idx_order);
682  shuffleTransposeMatrix<casacore::Bool, ExecuteMatrix4>(num_chan_, 0,
683  flag_, record.flag, pol_idx_order);
684  record.flag_row = anyTrue(flag_row_);
685 
686  record.num_pol = 4;
687  } else if (isSinglePol0()) {
688  record.setDataSize(1, num_chan_);
689  shuffleTransposeMatrix<casacore::Float, ExecuteMatrix1>(num_chan_,
690  0, data_, record.float_data, pol_idx_order);
691  shuffleTransposeMatrix<casacore::Bool, ExecuteMatrix1>(num_chan_, 0,
692  flag_, record.flag, pol_idx_order);
693  record.flag_row = flag_row_[0];
694 
695  record.num_pol = 1;
696  } else if (pcorr_type_.size() == 0) {
697  return false;
698  } else {// means strange combination of polarization types in DataChunk
699  throw AipsError("non-conforming combination of polarization accumulated");
700  }
701  for (casacore::Int i = 0; i < record.num_pol; ++i) {
702  record.corr_type[i] = col_stokes[pol_idx_order[i]];
703  }
704 
705  POST_END;
706  return true;
707  }
708 
709  bool getLinpol(MSDataRecord &record) {
710  POST_START;
711 
712  casacore::Vector<casacore::Int> const col_stokes(pcorr_type_);
713  std::vector<size_t> pol_idx_order;
714  getSortIndex(col_stokes, pol_idx_order);
715 
716  record.setFloat();
717  if (isDualPol()) {
718  // POL 0 and 1
719  record.setDataSize(2, num_chan_);
720  shuffleTransposeMatrix<casacore::Float, ExecuteMatrix2>(num_chan_,
721  0, data_, record.float_data, pol_idx_order);
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];
725  record.num_pol = 2;
726  } else if (isSinglePol0()) {
727  record.setDataSize(1, num_chan_);
728  shuffleTransposeMatrix<casacore::Float, ExecuteMatrix1>(num_chan_,
729  0, data_, record.float_data, pol_idx_order);
730  shuffleTransposeMatrix<casacore::Bool, ExecuteMatrix1>(num_chan_, 0,
731  flag_, record.flag, pol_idx_order);
732  record.flag_row = flag_row_[0];
733 
734  record.num_pol = 1;
735  } else if (pcorr_type_.size() == 0) {
736  return false;
737  } else {// means strange combination of polarization types in DataChunk
738  throw AipsError("non-conforming combination of polarization accumulated");
739  }
740  for (casacore::Int i = 0; i < record.num_pol; ++i) {
741  record.corr_type[i] = col_stokes[pol_idx_order[i]];
742  }
743 
744  POST_END;
745  return true;
746  }
747 
749  if (isFullPol()) {
750  return 4;
751  } else if (isDualPol()) {
752  return 2;
753  } else if (isSinglePol0() || isSinglePol1()) {
754  return 1;
755  } else {
756  return 0;
757  }
758  }
759 
761  return getNumPolLinear();
762  }
763 
765  if (isFullPol()) {
766  return 4;
767  } else if (isSinglePol0()) {
768  return 1;
769  } else {
770  return 0;
771  }
772  }
773 
775  if (isDualPol()) {
776  return 2;
777  } else if (isSinglePol0()) {
778  return 1;
779  } else {
780  return 0;
781  }
782  }
783 };
784 
786 private:
794 
795  template<class T, class C>
796  bool comp(T const &a, T const &b, C const &c) const {
797  if (a < b) {
798  return true;
799  } else if (a == b) {
800  return c();
801  } else {
802  return false;
803  }
804  }
805 
807  DataAccumulatorKey const &rhs) const {
808  return comp(lhs.antenna_id, rhs.antenna_id,
809  [&]() {return comp(lhs.field_id, rhs.field_id,
810  [&]() {return comp(lhs.feed_id, rhs.feed_id,
811  [&]() {return comp(lhs.spw_id, rhs.spw_id,
812  [&]() {return comp(lhs.pol_type, rhs.pol_type,
813  [&]() {return comp(lhs.intent, rhs.intent,
814  []() {return false;});});});});});});
815  }
816  };
817 
818 public:
820  pool_(), antenna_id_(), spw_id_(), field_id_(), feed_id_(), scan_(), subscan_(), intent_(), direction_(), interval_(), indexer_(), time_(
821  -1.0), is_free_() {
822  }
823 
824  virtual ~DataAccumulator() {
825  POST_START;
826 
827  for (auto iter = pool_.begin(); iter != pool_.end(); ++iter) {
828  delete *iter;
829  }
830 
831  POST_END;
832  }
833 
834  size_t getNumberOfChunks() const {
835  return pool_.size();
836  }
837 
838  size_t getNumberOfActiveChunks() const {
839  return std::count_if(pool_.begin(), pool_.end(),
840  [](DataChunk * const &c) {
841  return c->getNumPol() > 0;
842  });
843  }
844 
845  bool queryForGet(DataRecord const &record) const {
846  casacore::Double const time = record.time;
847  bool is_ready = (0.0 <= time_) && !(time_ == time);
848  return is_ready;
849  }
850 
851  bool queryForGet(casacore::Double const &time) const {
852  bool is_ready = (0.0 <= time_) && !(time_ == time);
853  return is_ready;
854  }
855 
856  void clear() {
857  for (auto iter = pool_.begin(); iter != pool_.end(); ++iter) {
858  (*iter)->clear();
859  }
860  time_ = -1.0;
861  }
862 
863  bool get(size_t ichunk, MSDataRecord &record) {
864  POST_START;
865 
866  if (pool_.size() == 0) {
867  return false;
868  } else if (ichunk >= pool_.size()) {
869  return false;
870  }
871  bool status = pool_[ichunk]->get(record);
872 // std::cout << "get Chunk status = " << status << std::endl;
873  if (!status) {
874  record.clear();
875  return status;
876  }
877  record.time = time_;
878  record.pol_type = pool_[ichunk]->getPolType();
879  record.antenna_id = antenna_id_[ichunk];
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];
886  record.direction = direction_[ichunk];
887  record.interval = interval_[ichunk];
888  record.temperature = temperature_[ichunk];
889  record.pressure = pressure_[ichunk];
890  record.rel_humidity = rel_humidity_[ichunk];
891  record.wind_speed = wind_speed_[ichunk];
892  record.wind_direction = wind_direction_[ichunk];
893 
894  POST_END;
895  return status;
896  }
897 
898  bool accumulate(DataRecord const &record) {
899  POST_START;
900 
901  if (!isValidRecord(record)) {
902 // std::cout << "record is not a valid one" << std::endl;
903  return false;
904  }
905 
906  casacore::Double time = record.time;
907  if (time_ < 0.0) {
908  time_ = time;
909  }
910  if (time_ != time) {
911 // std::cout << "timestamp mismatch" << std::endl;
912  return false;
913  }
914  casacore::Int antennaid = record.antenna_id;
915  casacore::Int spwid = record.spw_id;
916  casacore::Int fieldid = record.field_id;
917  casacore::Int feedid = record.feed_id;
918  casacore::Int scan = record.scan;
919  casacore::Int subscan = record.subscan;
920  casacore::String intent = record.intent;
921  casacore::String poltype = record.pol_type;
922  DataAccumulatorKey key;
923  key.antenna_id = record.antenna_id;
924  key.field_id = record.field_id;
925  key.feed_id = record.feed_id;
926  key.spw_id = record.spw_id;
927  key.intent = record.intent;
928  key.pol_type = record.pol_type;
929  casacore::Matrix<casacore::Double> const &direction = record.direction;
930  casacore::Double interval = record.interval;
931  casacore::Float temperature = record.temperature;
932  casacore::Float pressure = record.pressure;
933  casacore::Float rel_humidity = record.rel_humidity;
934  casacore::Float wind_speed = record.wind_speed;
935  casacore::Float wind_direction = record.wind_direction;
936  bool status = false;
937  auto iter = indexer_.find(key);
938 // std::cout << "(ant, spw, pol, pol_type, field, feed, intent) = ("
939 // << key.antenna_id << ", " << key.spw_id << ", " << record.pol<< ", " << key.pol_type << ", " << key.field_id << ", " << key.feed_id
940 // << ", " << key.intent << ", "
941 // << std::endl;
942  if (iter != indexer_.end()) {
943  casacore::uInt index = iter->second;
944  status = pool_[index]->accumulate(record);
945  if (status) {
946  antenna_id_[index] = antennaid;
947  spw_id_[index] = spwid;
948  field_id_[index] = fieldid;
949  feed_id_[index] = feedid;
950  scan_[index] = scan;
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;
960  }
961  } else {
962  pool_.push_back(new DataChunk(poltype));
963  antenna_id_.push_back(-1);
964  spw_id_.push_back(-1);
965  field_id_.push_back(-1);
966  feed_id_.push_back(-1);
967  scan_.push_back(-1);
968  subscan_.push_back(-1);
969  intent_.push_back("");
970  direction_.push_back(casacore::Matrix<casacore::Double>());
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);
977  casacore::uInt index = pool_.size() - 1;
978  indexer_[key] = index;
979  status = pool_[index]->accumulate(record);
980  if (status) {
981  antenna_id_[index] = antennaid;
982  spw_id_[index] = spwid;
983  field_id_[index] = fieldid;
984  feed_id_[index] = feedid;
985  scan_[index] = scan;
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;
995  }
996  }
997 
998 // std::cout << "status = " << status << std::endl;
999 // std::cout << "key (a" << key.antenna_id << ",f" << key.field_id << ",s"
1000 // << key.spw_id << ",i" << key.intent << ",p" << key.pol_type << ",d"
1001 // << key.feed_id << "(index " << indexer_[key] << "): TIME="
1002 // << time_ << " INTERVAL=" << interval << " polno=" << record.pol << std::endl;
1003  POST_END;
1004  return status;
1005  }
1006 
1007  casacore::String getPolType(size_t ichunk) const {
1008  assert(ichunk < pool_.size());
1009  return pool_[ichunk]->getPolType();
1010  }
1011 
1012  casacore::uInt getNumPol(size_t ichunk) const {
1013  assert(ichunk < pool_.size());
1014  return pool_[ichunk]->getNumPol();
1015  }
1016 
1017 private:
1018  bool isValidRecord(DataRecord const &record) {
1019 // std::cout << record.time << " " << record.interval << " "
1020 // << record.antenna_id << " " << record.field_id << " " << record.feed_id
1021 // << " " << record.spw_id << " " << record.scan << " " << record.subscan
1022 // << " " << record.direction << std::endl;
1023  return record.time > 0.0 && record.interval > 0.0
1024  && record.antenna_id >= 0 && record.field_id >= 0
1025  && record.feed_id >= 0 && record.spw_id >= 0 && record.scan >= 0
1026  && record.subscan >= 0 && !record.direction.empty();
1027  }
1028 
1029  std::vector<DataChunk *> pool_;
1030  std::vector<casacore::Int> antenna_id_;
1031  std::vector<casacore::Int> spw_id_;
1032  std::vector<casacore::Int> field_id_;
1033  std::vector<casacore::Int> feed_id_;
1034  std::vector<casacore::Int> scan_;
1035  std::vector<casacore::Int> subscan_;
1036  std::vector<casacore::String> intent_;
1037  std::vector<casacore::Matrix<casacore::Double> > direction_;
1038  std::vector<casacore::Double> interval_;
1039  std::vector<casacore::Float> temperature_;
1040  std::vector<casacore::Float> pressure_;
1041  std::vector<casacore::Float> rel_humidity_;
1042  std::vector<casacore::Float> wind_speed_;
1043  std::vector<casacore::Float> wind_direction_;
1044  std::map<DataAccumulatorKey, casacore::uInt, DataAccumulatorKey> indexer_;
1046  std::vector<bool> is_free_;
1047 };
1048 
1049 } //# NAMESPACE SDFILLER - END
1050 } //# NAMESPACE CASA - END
1051 
1052 #endif /* SINGLEDISH_FILLER_DATAACCUMULATOR_H_ */
A Vector of integers, for indexing into Array&lt;T&gt; objects.
Definition: IPosition.h:119
casacore::Matrix< casacore::Float > tsys
optional
Definition: DataRecord.h:533
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)
Definition: DataRecord.h:386
int Int
Definition: aipstype.h:50
#define POST_END
Definition: FillerUtil.h:18
casacore::String getPolType(size_t ichunk) const
Linearly Polarized intensity ((Q^2+U^2)^(1/2))
Definition: Stokes.h:110
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
Definition: DataRecord.h:511
std::vector< casacore::Stokes::StokesTypes > pcorr_type_
casacore::Float wind_speed
Definition: DataRecord.h:247
std::map< DataAccumulatorKey, casacore::uInt, DataAccumulatorKey > indexer_
size_t nelements() const
How many elements does this array have? Product of all axis lengths.
Definition: ArrayBase.h:99
const IPosition & shape() const
The length of each axis of the Matrix.
Definition: Matrix.h:295
bool accumulate(DataRecord const &record)
casacore::Float temperature
Definition: DataRecord.h:536
#define max(a, b)
Definition: hio.h:44
casacore::Float wind_speed
Definition: DataRecord.h:539
void setTcal1(MSDataRecord &record, ssize_t start_src)
void setTcal2(MSDataRecord &record, std::vector< size_t > order={})
casacore::Vector< casacore::Float > data
Definition: DataRecord.h:236
casacore::String pol_type
Definition: DataRecord.h:231
void setDataSize(size_t n, size_t m)
Definition: DataRecord.h:330
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.
Definition: ExprNode.h:1886
casacore::Stokes::StokesTypes pol
Definition: DataRecord.h:229
casacore::Float wind_direction
Definition: DataRecord.h:540
bool getCircular(MSDataRecord &record)
casacore::Int antenna_id
Definition: DataRecord.h:223
bool getLinear(MSDataRecord &record)
standard stokes parameters
Definition: Stokes.h:73
casacore::Matrix< casacore::Float > float_data
Definition: DataRecord.h:525
size_type size() const
Capacity, size.
Definition: String.h:342
casacore::Matrix< casacore::Bool > flag
Definition: DataRecord.h:527
String & resize(size_type n)
Resize by truncating or extending with copies of &lt;tt&gt;c&lt;/tt&gt; (default Char())
Definition: String.h:359
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
Definition: PlotTool.h:43
bool queryForGet(casacore::Double const &time) const
A 2-D Specialization of the Array class.
Bool empty() const
Is the array empty (i.e.
Definition: ArrayBase.h:106
casacore::Matrix< casacore::Float > tsys_
void setTsys2(MSDataRecord &record, std::vector< size_t > order={})
Tsys and Tcal assignment for 2 &amp; 4 pols.
casacore::Vector< casacore::Float > tsys
optional
Definition: DataRecord.h:241
StokesTypes
The Stokes types are defined by this enum.
Definition: Stokes.h:66
bool getLinpol(MSDataRecord &record)
ABSTRACT CLASSES Deliberately vague to be general enough to allow for many different types of data
Definition: PlotData.h:48
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_
void setPolType(casacore::String const &poltype)
casacore::Vector< casacore::Bool > flag
Definition: DataRecord.h:237
static String name(StokesTypes stokesType)
convert StokesTypes to String, Stokes::Undefined returns &quot;??&quot;.
void setTcalSize(size_t n, size_t m)
Definition: DataRecord.h:418
casacore::Vector< casacore::Int > corr_type
Definition: DataRecord.h:522
circular correlation products
Definition: Stokes.h:79
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
Definition: Stokes.h:85
casacore::Vector< casacore::Float > tcal
Definition: DataRecord.h:242
bool isValidRecord(DataRecord const &record)
casacore::Float rel_humidity
Definition: DataRecord.h:246
casacore::String getPolType() const
double Double
Definition: aipstype.h:55
casacore::Matrix< casacore::Complex > complex_data
Definition: DataRecord.h:526
casacore::Double interval
Definition: DataRecord.h:512
casacore::Double time
mandatory
Definition: DataRecord.h:221
String & assign(const string &str)
Assign.
Definition: String.h:419
const IPosition & shape() const
The length of the Vector.
Definition: Vector.h:293
std::vector< casacore::Double > interval_
std::vector< DataChunk * > pool_
bool isValidRecord(DataRecord const &record)
void indgen(TableVector< T > &tv, Int start, Int inc)
Definition: TabVecMath.h:400
bool Bool
Define the standard types used by Casacore.
Definition: aipstype.h:42
std::vector< casacore::String > intent_
std::vector< casacore::Int > field_id_
casacore::Float pressure
Definition: DataRecord.h:245
casacore::Matrix< casacore::Double > direction
Definition: DataRecord.h:523
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.
Definition: Matrix.h:305
casacore::uInt getNumPolCircular() const
bool operator()(DataAccumulatorKey const &lhs, DataAccumulatorKey const &rhs) const
float Float
Definition: aipstype.h:54
std::vector< casacore::Float > temperature_
void resetPolType(casacore::String const &poltype)
casacore::String pol_type
Definition: DataRecord.h:521
std::vector< casacore::Int > subscan_
casacore::Float temperature
Definition: DataRecord.h:244
TableExprNode shape(const TableExprNode &array)
Function operating on any scalar or array resulting in a Double array containing the shape...
Definition: ExprNode.h:1944
casacore::Matrix< casacore::Float > tcal
Definition: DataRecord.h:534
casacore::Float wind_direction
Definition: DataRecord.h:248
std::vector< casacore::Matrix< casacore::Double > > direction_
casacore::String intent
Definition: DataRecord.h:520
void setTsys1(MSDataRecord &record, ssize_t start_src)
casacore::Matrix< casacore::Double > direction
Definition: DataRecord.h:232
casacore::Float rel_humidity
Definition: DataRecord.h:538
std::vector< casacore::Float > rel_humidity_
std::vector< casacore::Float > wind_speed_
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
Definition: RFCommon.h:172
Base class for all Casacore library errors.
Definition: Error.h:134
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)
Definition: TabVecLogic.h:168
casacore::String intent
Definition: DataRecord.h:230
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.
Definition: String.h:223
casacore::uInt getNumPol(size_t ichunk) const
Linear Polarization Angle (0.5 arctan(U/Q)) (in radians)
Definition: Stokes.h:116
#define POST_START
Definition: FillerUtil.h:17
size_t size() const
Definition: ArrayBase.h:101
casacore::Matrix< casacore::Float > tcal_
casacore::Float pressure
Definition: DataRecord.h:537
std::vector< casacore::Float > pressure_
std::vector< casacore::Int > antenna_id_
casacore::Double interval
Definition: DataRecord.h:222
void freeStorage(const T *&storage, Bool deleteIt) const
If deleteIt is set, delete &quot;storage&quot;.
casacore::Matrix< casacore::Float > data_
bool queryForGet(DataRecord const &record) const
casacore::Vector< casacore::Bool > flag_row_
unsigned int uInt
Definition: aipstype.h:51
casacore::uInt getNumPol() const
casacore::Matrix< casacore::Bool > flag_
casacore::Bool flag_row
Definition: DataRecord.h:238
#define casacore
&lt;X11/Intrinsic.h&gt; #defines true, false, casacore::Bool, and String.
Definition: X11Intrinsic.h:42