casa  5.7.0-16
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
ScantableIterator.h
Go to the documentation of this file.
1 /*
2  * ScantableIterator.h
3  *
4  * Created on: Jan 28, 2016
5  * Author: nakazato
6  */
7 
8 #ifndef SINGLEDISH_FILLER_SCANTABLEITERATOR_H_
9 #define SINGLEDISH_FILLER_SCANTABLEITERATOR_H_
10 
14 
16 
26 
27 using namespace casacore;
28 
29 namespace {
30 template<class T>
31 inline void getDataRangePerId(casacore::Vector<casacore::uInt> const &index_list,
32  casacore::Vector<T> const &id_list, size_t start,
33  size_t end, std::map<T, casacore::Block<casacore::uInt> > &range_index) {
34  casacore::uInt id_prev = id_list[index_list[start]];
35  casacore::uInt id_min = index_list[start];
36  casacore::uInt id_max = 0;
37  casacore::Block < casacore::uInt > current_index(2);
38  for (casacore::uInt i = start + 1; i < end; ++i) {
39  casacore::uInt j = index_list[i];
40  casacore::uInt current_id = id_list[j];
41 // std::cout << "weather_id = " << weather_id << " id_prev = " << id_prev
42 // << " time range (" << time_min << "," << time_max << ")" << std::endl;
43  if (current_id != id_prev) {
44  id_max = index_list[i - 1];
45  current_index[0] = id_min;
46  current_index[1] = id_max;
47  range_index[id_prev] = current_index;
48 
49  id_prev = current_id;
50  id_min = j;
51  }
52  }
53  casacore::uInt last_id = id_list[index_list[end - 1]];
54  if (range_index.find(last_id) == range_index.end()) {
55  id_max = index_list[end - 1];
56  current_index[0] = id_min;
57  current_index[1] = id_max;
58  range_index[last_id] = current_index;
59  }
60 }
61 
62 }
63 
64 namespace casa { //# NAMESPACE CASA - BEGIN
65 
67 public:
69  current_iter_(0), main_table_(table), num_iter_(0) {
70  }
72  }
73  void initialize(size_t num_iter) {
74  num_iter_ = num_iter;
75  current_iter_ = 0;
76  }
77  bool moreData() const {
78  return current_iter_ < num_iter_;
79  }
80  void next() {
81  ++current_iter_;
82  }
83 
84 protected:
85  size_t current_iter_;
87 
88 private:
89  size_t num_iter_;
90 };
91 
93 public:
94  typedef std::map<casacore::Int, casacore::Int> Product;
97  casacore::TableRecord const &header = main_table_.keywordSet();
98  sub_table_ = header.asTable("FREQUENCIES");
99  //size_t nrow = sub_table_.nrow();
100  casacore::ScalarColumn < casacore::uInt > ifno_column(main_table_, "IFNO");
101  casacore::Vector < casacore::uInt > ifno_list = ifno_column.getColumn();
102  casacore::Sort sorter;
103  sorter.sortKey(ifno_list.data(), TpUInt);
105  casacore::uInt n = sorter.sort(index_vector, ifno_list.nelements(),
107 
108  initialize(n);
109  ifno_list_.resize(n);
110  for (casacore::uInt i = 0; i < n; ++i) {
111  ifno_list_[i] = ifno_list[index_vector[i]];
112  }
113 
114  casacore::ScalarColumn < casacore::uInt > freq_id_column(main_table_, "FREQ_ID");
115 
116  // attach columns
117  id_column_.attach(sub_table_, "ID");
118  refpix_column_.attach(sub_table_, "REFPIX");
119  refval_column_.attach(sub_table_, "REFVAL");
120  increment_column_.attach(sub_table_, "INCREMENT");
121  id_list_ = id_column_.getColumn();
122  }
124  }
125 
127  size_t const irow = current_iter_;
128 // std::cout << "getEntry for row " << irow << std::endl;
129  casacore::Int spw_id = ifno_list_[irow];
130  casacore::Table subtable = main_table_(main_table_.col("IFNO") == (casacore::uInt) spw_id, 1);
131  casacore::ScalarColumn < casacore::uInt > freq_id_column(subtable, "FREQ_ID");
132  casacore::uInt freq_id = freq_id_column(0);
133  casacore::Int jrow = -1;
134  for (casacore::uInt i = 0; i < id_list_.size(); ++i) {
135  if (id_list_[i] == freq_id) {
136  jrow = (casacore::Int) i;
137  break;
138  }
139  }
140  casacore::ArrayColumn<casacore::uChar> flag_column(subtable, "FLAGTRA");
141  casacore::Int num_chan = flag_column.shape(0)[0];
142  casacore::String freq_frame = sub_table_.keywordSet().asString("BASEFRAME");
143  casacore::MFrequency::Types frame_type;
144  casacore::Bool status = casacore::MFrequency::getType(frame_type, freq_frame);
145  if (!status) {
146  frame_type = casacore::MFrequency::N_Types;
147  }
148  casacore::Double refpix = refpix_column_(jrow);
149  casacore::Double refval = refval_column_(jrow);
150  casacore::Double increment = increment_column_(jrow);
151 // std::cout << "spw " << spw_id << " nchan " << num_chan << " mfr "
152 // << (casacore::Int) frame_type << " (" << freq_frame << ") ref " << refpix << ", "
153 // << refval << ", " << increment << std::endl;
154  record.spw_id = spw_id;
155  record.num_chan = num_chan;
156  record.meas_freq_ref = frame_type;
157  record.refpix = refpix;
158  record.refval = refval;
159  record.increment = increment;
160 
161  // update product
162  product_[spw_id] = num_chan;
163  }
164  virtual void getProduct(Product *p) {
165  if (p) {
166  for (auto iter = product_.begin(); iter != product_.end(); ++iter) {
167  (*p)[iter->first] = iter->second;
168  }
169  }
170  }
171 
172 private:
181 };
182 
184 public:
185  typedef std::map<casacore::String, casacore::Int> Product;
187  ScantableIteratorInterface(table), row_list_(), is_reserved_(), field_column_(
188  main_table_, "FIELDNAME"), source_column_(main_table_, "SRCNAME"), time_column_(
189  main_table_, "TIME"), direction_column_(main_table_, "SRCDIRECTION"), scanrate_column_(
190  main_table_, "SCANRATE"), direction_storage_(2, 2, 0.0) {
191  casacore::Vector < casacore::String > field_name_list = field_column_.getColumn();
192  casacore::Sort sorter;
193  sorter.sortKey(field_name_list.data(), TpString);
194  casacore::uInt n = sorter.sort(row_list_, field_name_list.size(),
196  is_reserved_.resize(n);
197  is_reserved_ = false;
198  initialize(n);
199  }
200 
202  }
203 
205  casacore::uInt const irow = row_list_[current_iter_];
206  casacore::String field_name_with_id = field_column_(irow);
207  auto pos = field_name_with_id.find("__");
208  auto defaultFieldId =
209  [&]() {
210  casacore::Int my_field_id = 0;
211  while (is_reserved_[my_field_id] && (casacore::uInt)my_field_id < is_reserved_.size()) {
212  my_field_id++;
213  }
214  if ((casacore::uInt)my_field_id >= is_reserved_.size()) {
215  throw casacore::AipsError("Internal inconsistency in FIELD_ID numbering");
216  }
217  is_reserved_[my_field_id] = true;
218  return my_field_id;
219  };
220  if (pos != casacore::String::npos) {
221  record.name = field_name_with_id.substr(0, pos);
222  casacore::Int field_id = casacore::String::toInt(field_name_with_id.substr(pos + 2));
223  if (field_id < 0) {
224  record.field_id = defaultFieldId();
225  } else if ((casacore::uInt) field_id >= is_reserved_.size()
226  || !is_reserved_[field_id]) {
227  record.field_id = field_id;
228  is_reserved_[field_id] = true;
229  } else {
230  record.field_id = defaultFieldId();
231  }
232  } else {
233  record.name = field_name_with_id;
234  record.field_id = defaultFieldId();
235  }
236  record.time = time_column_(irow) * 86400.0;
237  record.source_name = source_column_(irow);
240  > direction(direction_storage_(casacore::IPosition(2, 0, 0), casacore::IPosition(2, 1, 0)));
241 // std::cout << "direction = " << direction << " (shape " << direction.shape()
242 // << ")" << std::endl;
243  direction_storage_.column(0) = direction_column_(irow);
244  if (scanrate_column_.isDefined(irow)) {
245  casacore::Vector < casacore::Double > scan_rate = scanrate_column_(irow);
246  if (anyNE(scan_rate, 0.0)) {
247  direction_storage_.column(1) = scan_rate;
248  direction.reference(direction_storage_);
249  }
250  }
251 // std::cout << "direction = " << direction << " (shape " << direction.shape()
252 // << ")" << std::endl;
253  record.direction = direction;
254 
255  // update product
256  product_[field_name_with_id] = record.field_id;
257  }
258  virtual void getProduct(Product *p) {
259  if (p) {
260  for (auto iter = product_.begin(); iter != product_.end(); ++iter) {
261  (*p)[iter->first] = iter->second;
262  }
263  }
264  }
265 
266 private:
276 };
277 
279 public:
280  typedef void * Product;
282  ScantableIteratorInterface(table), name_column_(main_table_, "SRCNAME"), direction_column_(
283  main_table_, "SRCDIRECTION"), proper_motion_column_(main_table_,
284  "SRCPROPERMOTION"), sysvel_column_(main_table_, "SRCVELOCITY"), molecule_id_column_(
285  main_table_, "MOLECULE_ID"), ifno_column_(main_table_, "IFNO"), molecules_table_(), row_list_(), source_id_map_() {
286  casacore::TableRecord const &header = main_table_.keywordSet();
287  molecules_table_ = header.asTable("MOLECULES");
288  restfrequency_column_.attach(molecules_table_, "RESTFREQUENCY");
289  molecule_name_column_.attach(molecules_table_, "NAME");
290  casacore::Vector < casacore::String > source_name_list = name_column_.getColumn();
291  casacore::Vector < casacore::uInt > ifno_list = ifno_column_.getColumn();
292  casacore::Sort sorter;
293  sorter.sortKey(source_name_list.data(), TpString);
295  casacore::uInt num_unique = sorter.sort(unique_vector, source_name_list.size(),
297  for (casacore::uInt i = 0; i < num_unique; ++i) {
298  source_id_map_[name_column_(unique_vector[i])] = (casacore::Int) i;
299  }
300  casacore::Sort sorter2;
301  sorter2.sortKey(source_name_list.data(), TpString);
302  sorter2.sortKey(ifno_list.data(), TpUInt);
303  unique_vector.resize();
304  num_unique = sorter2.sort(row_list_, source_name_list.size(),
306 // for (casacore::uInt i = 0; i < num_unique; ++i) {
307 // std::cout << i << ": SRCNAME \"" << name_column_(row_list_[i])
308 // << "\" IFNO " << ifno_column_(row_list_[i]) << std::endl;
309 // }
310  initialize(num_unique);
311 
312  // generate molecule_id_map_
313  casacore::ScalarColumn < casacore::uInt > id_column(molecules_table_, "ID");
314  casacore::Vector < casacore::uInt > molecule_id_list = id_column.getColumn();
315  for (casacore::uInt i = 0; i < id_column.nrow(); ++i) {
316  molecule_id_map_[molecule_id_list[i]] = i;
317  }
318 
319  // generate sorted_index_
320  casacore::uInt nrow_main = main_table_.nrow();
321  casacore::ScalarColumn < casacore::String > srcname_column(main_table_, "SRCNAME");
322  casacore::ScalarColumn < casacore::uInt > ifno_column(main_table_, "IFNO");
323  casacore::ScalarColumn < casacore::Double > time_column(main_table_, "TIME");
324  casacore::ScalarColumn < casacore::Double > &interval_column = time_column;
325  casacore::Sort sorter3;
326  casacore::Vector < casacore::String > srcname_list = srcname_column.getColumn();
327  casacore::Vector < casacore::Double > time_list = time_column.getColumn();
328  sorter3.sortKey(srcname_list.data(), TpString, 0, casacore::Sort::Ascending);
329  sorter3.sortKey(ifno_list.data(), TpUInt, 0, casacore::Sort::Ascending);
330  sorter3.sortKey(time_list.data(), TpDouble, 0, casacore::Sort::Ascending);
332  sorter3.sort(index_list, nrow_main, casacore::Sort::QuickSort);
333 
334  std::vector<size_t> srcname_boundary;
335  srcname_boundary.push_back(0u);
336  casacore::String current = srcname_list[index_list[0]];
337  for (casacore::uInt i = 1; i < nrow_main; ++i) {
338  casacore::String name = srcname_list[index_list[i]];
339  if (current != name) {
340  srcname_boundary.push_back(i);
341  current = name;
342  }
343  }
344  srcname_boundary.push_back(nrow_main);
345 
346  constexpr double kDay2Sec = 86400.0;
347  interval_column.attach(main_table_, "INTERVAL");
348  time_range_.clear();
349  for (size_t i = 0; i < srcname_boundary.size() - 1; ++i) {
350  casacore::String name = srcname_list[index_list[srcname_boundary[i]]];
351  size_t start = srcname_boundary[i];
352  size_t end = srcname_boundary[i + 1];
353  std::map<casacore::uInt, casacore::Block<casacore::Double> > range;
354  std::map<casacore::uInt, casacore::Block<casacore::uInt> > range_index;
355  getDataRangePerId(index_list, ifno_list, start, end,
356  range_index);
357  for (auto iter = range_index.begin(); iter != range_index.end(); ++iter) {
358  casacore::Block<casacore::uInt> idx = iter->second;
359  casacore::Block<casacore::Double> time_range(2);
360  time_range[0] = time_list[idx[0]] * kDay2Sec
361  - 0.5 * interval_column(idx[0]);
362  time_range[1] = time_list[idx[1]] * kDay2Sec
363  + 0.5 * interval_column(idx[1]);
364  range[iter->first] = time_range;
365  }
366  time_range_[name] = range;
367  }
368 
369 // for (auto i = time_range_.begin(); i != time_range_.end(); ++i) {
370 // std::cout << "SRCNAME \"" << i->first << "\": " << std::endl;
371 // for (auto j = i->second.begin(); j != i->second.end(); ++j) {
372 // std::cout << " " << j->first << ": " << j->second[0] << " "
373 // << j->second[1] << std::endl;
374 // }
375 // }
376  }
377 
379  }
380 
382  casacore::uInt const irow = row_list_[current_iter_];
383  casacore::uInt const ifno = ifno_column_(irow);
384  record.name = name_column_(irow);
385  record.source_id = source_id_map_[record.name];
386  record.spw_id = ifno; //ifno_column_(irow);
388  casacore::Quantum<casacore::Vector<casacore::Double> >(direction_column_(irow), "rad"),
390  record.proper_motion = proper_motion_column_(irow);
391  casacore::uInt molecule_id = molecule_id_column_(irow);
392  auto iter = molecule_id_map_.find(molecule_id);
393  if (iter != molecule_id_map_.end()) {
394  casacore::uInt jrow = iter->second;
395  if (restfrequency_column_.isDefined(jrow)) {
396  record.rest_frequency = restfrequency_column_(jrow);
397  }
398  if (molecule_name_column_.isDefined(jrow)) {
399  record.transition = molecule_name_column_(jrow);
400  }
401  }
402  // 2016/02/04 TN
403  // comment out the following else block since if no ID is found in
404  // molecule_id_map_ it indicates that there is no corresponding
405  // entry in MOLECULES table for given MOLECULE_ID. Serch result is
406  // always empty table.
407 // else {
408 // casacore::Table t = molecules_table_(molecules_table_.col("ID") == molecule_id, 1);
409 // if (t.nrow() == 1) {
410 // casacore::ArrayColumn<casacore::Double> rest_freq_column(t, "RESTFREQUENCY");
411 // casacore::ArrayColumn<casacore::String> molecule_name_column(t, "NAME");
412 // if (rest_freq_column.isDefined(0)) {
413 // record.rest_frequency = rest_freq_column(0);
414 // }
415 // if (molecule_name_column.isDefined(0)) {
416 // record.transition = molecule_name_column(0);
417 // }
418 // }
419 // }
420  casacore::Double sysvel = sysvel_column_(irow);
421  record.num_lines = record.rest_frequency.size();
422  record.sysvel = casacore::Vector < casacore::Double > (record.num_lines, sysvel);
423 
424 // casacore::Table t = main_table_(
425 // main_table_.col("SRCNAME") == record.name
426 // && main_table_.col("IFNO") == record.spw_id);
427 // time_column_.attach(t, "TIME");
428 // casacore::Vector < casacore::Double > time_list = time_column_.getColumn();
429 // casacore::Sort sorter;
430 // sorter.sortKey(time_list.data(), TpDouble);
431 // casacore::Vector < casacore::uInt > index_vector;
432 // casacore::uInt n = sorter.sort(index_vector, time_list.size());
433 // interval_column_.attach(t, "INTERVAL");
434 // constexpr double kDay2Sec = 86400.0;
435 // casacore::Double time_min = time_list[index_vector[0]] * kDay2Sec
436 // - 0.5 * interval_column_(index_vector[0]);
437 // casacore::Double time_max = time_list[index_vector[n - 1]] * kDay2Sec
438 // + 0.5 * interval_column_(index_vector[n - 1]);
439  casacore::Block<casacore::Double> const &time_range = time_range_[record.name][ifno];
440  casacore::Double time_min = time_range[0];
441  casacore::Double time_max = time_range[1];
442  record.time = 0.5 * (time_min + time_max);
443  record.interval = (time_max - time_min);
444  }
445  virtual void getProduct(Product */*p*/) {
446 
447  }
448 
449 private:
462  std::map<casacore::String, casacore::Int> source_id_map_;
463  std::map<casacore::uInt, casacore::uInt> molecule_id_map_;
464  std::map<casacore::String, std::map<casacore::uInt, casacore::Block<casacore::Double> > > time_range_;
465 };
466 
467 } //# NAMESPACE CASA - END
468 
469 #endif /* SINGLEDISH_FILLER_SCANTABLEITERATOR_H_ */
A Vector of integers, for indexing into Array&lt;T&gt; objects.
Definition: IPosition.h:119
virtual void getProduct(Product *)
casacore::ScalarColumn< casacore::String > field_column_
A Measure: astronomical direction.
Definition: MDirection.h:174
casacore::ScalarColumn< casacore::uInt > id_column_
std::map< casacore::String, casacore::Int > source_id_map_
static Bool getType(MFrequency::Types &tp, const String &in)
Translate string to reference code.
int Int
Definition: aipstype.h:50
ScantableSourceIterator(casacore::Table const &table)
static Int toInt(const String &s, Bool chk=False)
Convert a string to an Int, Float or Double.
casacore::Vector< casacore::Double > sysvel
Definition: SourceRecord.h:38
ScantableFieldIterator(casacore::Table const &table)
casacore::ScalarColumn< casacore::Double > time_column_
ScantableIteratorInterface(casacore::Table const &table)
casacore::ArrayColumn< casacore::Double > scanrate_column_
size_t nelements() const
How many elements does this array have? Product of all axis lengths.
Definition: ArrayBase.h:99
Main interface class to a read/write table.
Definition: Table.h:153
casacore::Int source_id
mandatory
Definition: SourceRecord.h:25
casacore::Matrix< casacore::Double > direction
Definition: FieldRecord.h:43
casacore::Vector< casacore::Bool > is_reserved_
casacore::Vector< casacore::String > transition
Definition: SourceRecord.h:36
void getEntry(sdfiller::FieldRecord &record)
IPosition shape(uInt rownr) const
Get the shape of an array in a particular cell.
Definition: ArrayColumn.h:165
Table asTable(const RecordFieldId &) const
Get the table from the given field.
casacore::ScalarColumn< casacore::uInt > ifno_column_
casacore::ScalarColumn< casacore::String > source_column_
uInt nrow() const
Get the number of rows in the column.
Definition: TableColumn.h:197
void getEntry(sdfiller::SpectralWindowRecord &record)
casacore::ScalarColumn< casacore::uInt > molecule_id_column_
A 2-D Specialization of the Array class.
casacore::String source_name
Definition: FieldRecord.h:37
ABSTRACT CLASSES Abstract class for colors Any implementation of color should be able to provide a hexadecimal form of the if a human readable name(i.e."black").In many places throughout the plotter
const_iterator end() const
Bool anyNE(const TableVector< T > &l, const TableVector< T > &r)
Definition: TabVecLogic.h:173
T * data()
Get a pointer to the beginning of the array.
Definition: Array.h:597
ScantableFrequenciesIterator(casacore::Table const &table)
Sort on one or more keys, ascending and/or descending.
Definition: Sort.h:248
void attach(const Table &table, const String &columnName)
Attach a column to the object.
Definition: ScalarColumn.h:131
virtual void getProduct(Product *p)
std::map< casacore::String, std::map< casacore::uInt, casacore::Block< casacore::Double > > > time_range_
casacore::ArrayColumn< casacore::String > molecule_name_column_
virtual void getProduct(Product *p)
casacore::ScalarColumn< casacore::Double > increment_column_
casacore::Int field_id
meta
Definition: FieldRecord.h:36
double Double
Definition: aipstype.h:55
casacore::Vector< casacore::uInt > row_list_
casacore::ScalarColumn< casacore::Double > time_column_
String substr(size_type pos=0, size_type n=npos) const
Get a sub string.
Definition: String.h:570
casacore::ScalarColumn< casacore::Double > sysvel_column_
bool Bool
Define the standard types used by Casacore.
Definition: aipstype.h:42
casacore::ScalarColumn< casacore::String > name_column_
casacore::ScalarColumn< casacore::Double > refval_column_
casacore::Vector< casacore::Double > rest_frequency
Definition: SourceRecord.h:37
Quantities (i.e. dimensioned values)
Definition: QuantumHolder.h:44
casacore::Double time
Definition: FieldRecord.h:42
casacore::Matrix< casacore::Double > direction_storage_
A hierarchical collection of named fields of various types.
Definition: TableRecord.h:182
casacore::ArrayColumn< casacore::Double > direction_column_
casacore::Vector< casacore::uInt > id_list_
casacore::ArrayColumn< casacore::Double > direction_column_
casacore::MDirection direction
Definition: SourceRecord.h:30
casacore::Vector< casacore::Double > proper_motion
Definition: SourceRecord.h:39
size_type find(const string &str, size_type pos=0) const
Search functions.
Definition: String.h:644
casacore::String name
mandatory
Definition: FieldRecord.h:41
casacore::ArrayColumn< casacore::Double > restfrequency_column_
void getEntry(sdfiller::SourceRecord &record)
Base class for all Casacore library errors.
Definition: Error.h:134
casacore::MDirection::Types frame
Definition: FieldRecord.h:38
casacore::Double interval
Definition: SourceRecord.h:29
std::map< casacore::Int, casacore::Int > Product
String: the storage and methods of handling collections of characters.
Definition: String.h:223
std::map< casacore::uInt, casacore::uInt > molecule_id_map_
void initialize(size_t num_iter)
casacore::Vector< casacore::uInt > ifno_list_
casacore::ArrayColumn< casacore::Double > proper_motion_column_
size_t size() const
Definition: ArrayBase.h:101
void sortKey(const void *data, DataType, uInt increment=0, Order=Ascending)
Define a sort key (the most significant key should be defined first).
casacore::Table const main_table_
Types
Types of known MFrequencies Warning: The order defines the order in the translation matrix FromTo in...
Definition: MFrequency.h:176
void resize(size_t len, Bool copyValues=False)
Definition: Vector.h:167
virtual void reference(const Array< T > &other)
Create a reference to &quot;other&quot;, which must be of dimension one.
static const size_type npos
Definition: String.h:244
casacore::ScalarColumn< casacore::Double > interval_column_
casacore::ScalarColumn< casacore::Double > refpix_column_
uInt sort(Vector< uInt > &indexVector, uInt nrrec, int options=DefaultSort, Bool tryGenSort=True) const
Sort the data array of nrrec records.
std::map< casacore::String, casacore::Int > Product
unsigned int uInt
Definition: aipstype.h:51
void getColumn(Vector< T > &vec, Bool resize=False) const
Get the vector of all values in the column.
#define casacore
&lt;X11/Intrinsic.h&gt; #defines true, false, casacore::Bool, and String.
Definition: X11Intrinsic.h:42
casacore::Vector< casacore::uInt > row_list_