2 #include "purify/config.h"
5 #include <casacore/casa/Arrays/IPosition.h>
6 #include <casacore/tables/TaQL/ExprNode.h>
20 auto i_result = tables_->find(tabname);
21 if (i_result == tables_->end())
22 i_result = tables_->emplace(tabname, ::casacore::Table(tabname)).first;
24 return i_result->second;
28 if (
table().nrow() == 0)
return 0;
29 auto const column = array_column<::casacore::Double>(
"CHAN_FREQ",
"SPECTRAL_WINDOW");
30 auto const orig =
column.shape(0);
31 for (t_uint i(1); i <
column.nrow(); ++i)
32 if (orig !=
column.shape(i))
33 throw std::runtime_error(
"Can only do rectangular measurement set for now");
48 std::tuple<t_uint, std::string>
const &i)
const {
49 if (std::get<0>(i) >=
size())
throw std::out_of_range(
"Not that many channels");
53 std::string MeasurementSet::ChannelWrapper::filter()
const {
54 std::ostringstream sstr;
55 sstr <<
"WHERE NOT any(FLAG[" << channel_ <<
",])";
56 if (not filter_.empty()) sstr <<
"AND " << filter_;
59 std::string MeasurementSet::ChannelWrapper::index(std::string
const &variable)
const {
60 std::ostringstream sstr;
61 sstr << variable <<
"[" << channel_ <<
",]";
65 Vector<t_real> MeasurementSet::ChannelWrapper::joined_spectral_window(
66 std::string
const &
column)
const {
67 auto const raw = raw_spectral_window(
column);
68 auto const ids = ms_.column<::casacore::Int>(
"DATA_DESC_ID", filter());
70 table_column<::casacore::Int>(ms_.table(
"DATA_DESCRIPTION"),
"SPECTRAL_WINDOW_ID");
71 Vector<t_real> result(ids.size());
72 for (Eigen::DenseIndex i(0); i < ids.size(); ++i) {
73 assert(ids(i) < spids.size());
74 assert(spids(ids(i)) < raw.size());
75 result(i) = raw(spids(ids(i)));
81 std::ostringstream sstr;
82 sstr <<
"USING STYLE PYTHON SELECT FLAG[" << channel_ <<
",] as R FROM $1 WHERE NOT any(FLAG["
84 if (not filter_.empty()) sstr <<
"AND " << filter_;
85 auto const taql_table = ::casacore::tableCommand(sstr.str(), ms_.table());
86 return taql_table.table().nrow() > 0;
89 std::string MeasurementSet::ChannelWrapper::stokes(std::string
const &pol,
90 std::string
const &
column)
const {
91 std::ostringstream sstr;
92 sstr <<
"mscal.stokes(" <<
column <<
", '" << pol <<
"')";
96 Vector<t_real> MeasurementSet::ChannelWrapper::raw_spectral_window(std::string
const &stuff)
const {
97 std::ostringstream sstr;
98 sstr << stuff <<
"[" << channel_ <<
"]";
99 return table_column<t_real>(ms_.table(
"SPECTRAL_WINDOW"), sstr.str());
103 std::string
const &filter)
const {
104 auto const field_ids_raw = column<::casacore::Int>(
"FIELD_ID", filter);
105 auto const source_ids_raw = table_column<::casacore::Int>(
table(
"FIELD"),
"SOURCE_ID");
106 std::set<::casacore::Int> source_ids;
107 for (Eigen::DenseIndex i(0); i < field_ids_raw.size(); ++i) {
108 assert(field_ids_raw(i) < source_ids_raw.size());
109 source_ids.insert(source_ids_raw(field_ids_raw(i)));
111 if (source_ids.size() == 0 and source_ids_raw.size() > 0) {
113 "Could not find sources. Try different filter, no matching data in channel. "
114 "Currently using filter: " +
116 Vector<t_real> original(2);
120 }
else if (source_ids_raw.size() == 0)
121 throw std::runtime_error(
"Could not find sources. Cannot determine direction");
122 auto const directions = table_column<::casacore::Double>(
table(
"SOURCE"),
"DIRECTION");
123 auto const original = directions.row(*source_ids.begin());
124 for (
auto const other : source_ids)
125 if (not directions.row(other).isApprox(original, tolerance))
126 throw std::runtime_error(
"Found more than one direction");
132 wrapper_ = std::make_shared<value_type>(channel_, ms_, filter_);
142 if (not same_measurement_set(
c))
143 throw std::runtime_error(
"Iterators are not over the same measurement set");
144 return channel_ ==
c.channel_;
148 const std::vector<t_int> &channels_input,
149 std::string
const &filter) {
155 const std::vector<t_int> &channels,
156 std::string
const &filter) {
159 if (std::abs(uv1.
ra - uv2.ra) > 1e-6)
160 throw std::runtime_error(
filename +
": wrong RA in pointing.");
161 if (std::abs(uv1.
dec - uv2.dec) > 1e-6)
162 throw std::runtime_error(
filename +
": wrong DEC in pointing.");
165 uv.
u = Vector<t_real>::Zero(uv1.
size() + uv2.size());
166 uv.
v = Vector<t_real>::Zero(uv1.
size() + uv2.size());
167 uv.
w = Vector<t_real>::Zero(uv1.
size() + uv2.size());
168 uv.
vis = Vector<t_complex>::Zero(uv1.
size() + uv2.size());
169 uv.
weights = Vector<t_complex>::Zero(uv1.
size() + uv2.size());
170 uv.
u.segment(0, uv1.
size()) = uv1.
u;
171 uv.
v.segment(0, uv1.
size()) = uv1.
v;
172 uv.
w.segment(0, uv1.
size()) = uv1.
w;
175 uv.
u.segment(uv1.
size(), uv2.size()) = uv2.u;
176 uv.
v.segment(uv1.
size(), uv2.size()) = uv2.v;
177 uv.
w.segment(uv1.
size(), uv2.size()) = uv2.w;
178 uv.
vis.segment(uv1.
size(), uv2.size()) = uv2.vis;
179 uv.
weights.segment(uv1.
size(), uv2.size()) = uv2.weights;
183 const stokes pol,
const std::vector<t_int> &channel,
184 std::string
const &filter) {
186 if (
filename.size() == 1)
return output;
187 for (
int i = 1; i <
filename.size(); i++)
192 const std::vector<t_int> &channels_input,
193 std::string
const &filter) {
196 std::vector<t_int> channels = channels_input;
197 if (channels.empty()) {
199 Vector<t_int> temp_vector = Vector<t_int>::LinSpaced(ms_file.
size(), 0, ms_file.
size());
200 if (temp_vector.size() == 1)
202 channels = std::vector<t_int>(temp_vector.data(), temp_vector.data() + temp_vector.size());
206 for (
auto channel_number : channels) {
207 rows += ms_file[channel_number].
size();
211 uv_data.
u = Vector<t_real>::Zero(rows);
212 uv_data.
v = Vector<t_real>::Zero(rows);
213 uv_data.
w = Vector<t_real>::Zero(rows);
214 uv_data.
vis = Vector<t_complex>::Zero(rows);
215 uv_data.
weights = Vector<t_complex>::Zero(rows);
225 for (
auto channel_number : channels) {
226 PURIFY_DEBUG(
"Adding channel {} to plane...", channel_number);
227 if (channel_number < ms_file.
size()) {
228 auto const channel = ms_file[channel_number];
229 if (channel.size() > 0) {
230 if (uv_data.
ra != channel.right_ascension() or uv_data.
dec != channel.declination())
231 throw std::runtime_error(
"Channels contain multiple pointings.");
232 Vector<t_real>
const frequencies = channel.frequencies();
233 uv_data.
u.segment(row, channel.size()) = channel.lambda_u();
234 uv_data.
v.segment(row, channel.size()) = -channel.lambda_v();
235 uv_data.
w.segment(row, channel.size()) = channel.lambda_w();
236 t_real
const the_casa_factor = 2;
237 switch (polarization) {
239 uv_data.
vis.segment(row, channel.size()) = channel.I(
"DATA") * 0.5;
240 uv_data.
weights.segment(row, channel.size()).real() =
245 uv_data.
vis.segment(row, channel.size()) = channel.Q(
"DATA") * 0.5;
246 uv_data.
weights.segment(row, channel.size()).real() =
251 uv_data.
vis.segment(row, channel.size()) = channel.U(
"DATA") * 0.5;
252 uv_data.
weights.segment(row, channel.size()).real() =
257 uv_data.
vis.segment(row, channel.size()) = channel.V(
"DATA") * 0.5;
258 uv_data.
weights.segment(row, channel.size()).real() =
263 uv_data.
vis.segment(row, channel.size()) = channel.LL(
"DATA");
264 uv_data.
weights.segment(row, channel.size()).real() = channel.wLL(
269 uv_data.
vis.segment(row, channel.size()) = channel.LR(
"DATA");
270 uv_data.
weights.segment(row, channel.size()).real() = channel.wRL(
275 uv_data.
vis.segment(row, channel.size()) = channel.RL(
"DATA");
276 uv_data.
weights.segment(row, channel.size()).real() = channel.wRL(
281 uv_data.
vis.segment(row, channel.size()) = channel.RR(
"DATA");
282 uv_data.
weights.segment(row, channel.size()).real() = channel.wRR(
287 uv_data.
vis.segment(row, channel.size()) = channel.XX(
"DATA");
288 uv_data.
weights.segment(row, channel.size()).real() = channel.wXX(
293 uv_data.
vis.segment(row, channel.size()) = channel.XY(
"DATA");
294 uv_data.
weights.segment(row, channel.size()).real() = channel.wXY(
299 uv_data.
vis.segment(row, channel.size()) = channel.YX(
"DATA");
300 uv_data.
weights.segment(row, channel.size()).real() = channel.wYX(
305 uv_data.
vis.segment(row, channel.size()) = channel.YY(
"DATA");
306 uv_data.
weights.segment(row, channel.size()).real() = channel.wYY(
312 uv_data.
vis.segment(row, channel.size()) = channel.Q(
"DATA") +
I * channel.U(
"DATA");
313 uv_data.
weights.segment(row, channel.size()).real() =
322 row += channel.size();
334 const t_int &channel_width,
335 std::string
const &filter) {
337 std::vector<utilities::vis_params> channels_vis;
339 t_int
const total_channels = ms_file.size();
340 t_int
const planes = (channel_width == 0) ? 1 : std::floor(total_channels / channel_width);
342 for (
int i = 0; i < planes; i++) {
344 t_int
const end = std::min((i + 1) * channel_width, total_channels);
345 Vector<t_int> temp_block = Vector<t_int>::LinSpaced(channel_width, i * channel_width,
end);
346 if (channel_width == 1 or total_channels == i) temp_block(0) = i;
347 auto const block = std::vector<t_int>(temp_block.data(), temp_block.data() + temp_block.size());
354 const std::vector<t_int> &channels) {
356 t_real frequency_sum = 0;
357 t_real width_sum = 0.;
358 for (
auto channel_number : channels) {
359 auto const channel = ms_file[channel_number];
360 auto const frequencies = channel.frequencies();
361 auto const width = channel.width();
362 frequency_sum += (frequencies.array() * width.array()).sum();
363 width_sum += width.sum();
365 return frequency_sum / width_sum / 1e6;
369 if (ms_.table().nrow() == 0)
return 0;
370 std::ostringstream sstr;
371 sstr <<
"USING STYLE PYTHON SELECT FLAG[" << channel_ <<
",] as R FROM $1 WHERE NOT any(FLAG["
372 << channel_ <<
",])";
373 if (not filter_.empty()) sstr <<
"AND " << filter_;
374 auto const taql_table = ::casacore::tableCommand(sstr.str(), ms_.table());
375 auto const vtable = taql_table.table();
376 return vtable.nrow();
385 if (not same_measurement_set(
c))
386 throw std::runtime_error(
"Iterators are not over the same measurement set");
387 return channel_ >
c.channel_;
391 if (not same_measurement_set(
c))
392 throw std::runtime_error(
"Iterators are not over the same measurement set");
393 return channel_ >=
c.channel_;
t_uint size() const
Number of rows in a channel.
bool is_valid() const
Check if channel has any data.
const_iterator & operator+=(difference_type n)
const_iterator & operator++()
bool operator>(const_iterator const &c) const
bool operator>=(const_iterator const &c) const
bool operator==(const_iterator const &c) const
Interface around measurement sets.
Direction::Scalar right_ascension(t_real tolerance=1e-8, std::string const &filter="") const
Right ascention in radians.
std::string const & filename() const
Filename of the measurement set.
const_iterator end(std::string const &filter="") const
Iterates over channels.
::casacore::Table const & table(std::string const &name="") const
Gets table or subtable.
ChannelWrapper operator[](t_uint i) const
Returns wrapper over specific channel.
Direction direction(t_real tolerance=1e-8, std::string const &filter="") const
Direction (RA, DEC) in radians.
static std::string const default_filter
Default filter specifying which data to accept.
Eigen::Array< t_real, 2, 1 > Direction
Type for (RA, DEC) direction.
Direction::Scalar declination(t_real tolerance=1e-8, std::string const &filter="") const
Declination in radians.
void clear()
Clear memory.
const_iterator begin(std::string const &filter="") const
Iterates over channels.
std::size_t size() const
Number of channels in the measurement set.
Matrix< T > column(std::string const &column, std::string const &filter="") const
Data from a column.
#define PURIFY_LOW_LOG(...)
Low priority message.
#define PURIFY_DEBUG(...)
\macro Output some debugging
t_real average_frequency(const purify::casa::MeasurementSet &ms_file, std::string const &filter, const std::vector< t_int > &channels)
Return average frequency over channels.
utilities::vis_params read_measurementset(std::string const &filename, const stokes polarization, const std::vector< t_int > &channels_input, std::string const &filter)
Read measurement set into vis_params structure.
std::vector< utilities::vis_params > read_measurementset_channels(std::string const &filename, const stokes pol, const t_int &channel_width, std::string const &filter)
Read meassurement set into a vector of vis_params.
const t_real c
speed of light in vacuum
t_uint size() const
return number of measurements
Vector< t_complex > weights