Skip to content

Commit

Permalink
C++ pybind11 implementation of parallactic angles
Browse files Browse the repository at this point in the history
  • Loading branch information
sjperkins committed Sep 14, 2017
1 parent 7166c5a commit b5a0421
Show file tree
Hide file tree
Showing 3 changed files with 119 additions and 2 deletions.
93 changes: 93 additions & 0 deletions montblanc/util/casa_parangles.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
/*
<%
setup_pybind11(cfg)
cfg['compiler_args'] = ['-std=c++11', '-fvisibility=hidden']
cfg['libraries'] = ['casa_casa', 'casa_measures']
%>
*/

#include <iostream>
#include <vector>

#include <pybind11/pybind11.h>
#include <pybind11/numpy.h>

#include <casacore/measures/Measures/MCDirection.h>
#include <casacore/measures/Measures/MDirection.h>
#include <casacore/measures/Measures/MPosition.h>
#include <casacore/measures/Measures/MeasConvert.h>
#include <casacore/measures/Measures/MeasTable.h>
#include <casacore/measures/Measures/MEpoch.h>

namespace py = pybind11;

constexpr unsigned int flags = py::array::c_style | py::array::forcecast;

template <typename FT>
py::array_t<FT, flags> parallactic_angles(
py::array_t<FT, flags> times,
py::array_t<FT, flags> antenna_positions,
py::array_t<FT, flags> phase_centre)
{
py::gil_scoped_release release;

int na = antenna_positions.shape(0);
int ntimes = times.shape(0);

// Result array
py::array_t<FT, flags> angles({ntimes, na});

std::vector<casa::MPosition> itrf_antenna_positions;
itrf_antenna_positions.reserve(na);

// Compute antenna positions in ITRF
for(int ant=0; ant<na; ++ant)
{
const FT * x = antenna_positions.data(ant, 0);
const FT * y = antenna_positions.data(ant, 1);
const FT * z = antenna_positions.data(ant, 2);

itrf_antenna_positions.push_back(casa::MPosition(
casa::MVPosition(*x, *y, *z),
casa::MPosition::ITRF));
}

// Direction towards zenith
casa::MVDirection base_zenith(0, M_PI/2);

// Direction towards phase centre
casa::MVDirection phase_dir(*phase_centre.data(0), *phase_centre.data(1));

// For each time
for(int time=0; time<ntimes; ++time)
{
// Create a frame for this timestemp
casa::MeasFrame frame(casa::MEpoch(
casa::Quantum<double>(*times.data(time), "s"),
casa::MEpoch::UTC));

// For each antenna
for(int ant=0; ant<na; ++ant)
{
// Set the frame's position to the antenna position
frame.set(itrf_antenna_positions[ant]);

// Direction to the zenith in this frame
casa::MDirection mzenith(base_zenith, casa::MDirection::Ref(
casa::MDirection::AZELGEO, frame));

// Compute parallactic angle of phase direction w.r.t zenith
casa::MeasConvert<casa::MDirection> convert(mzenith, casa::MDirection::J2000);
*angles.mutable_data(time, ant) = phase_dir.positionAngle(convert().getValue());
}
}

return angles;
}

PYBIND11_MODULE(casa_parangles, m) {
m.doc() = "auto-compiled c++ extension";

m.def("parallactic_angles", &parallactic_angles<float>, py::return_value_policy::move);
m.def("parallactic_angles", &parallactic_angles<double>, py::return_value_policy::move);
}
25 changes: 25 additions & 0 deletions montblanc/util/parallactic_angles.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,16 @@
# You should have received a copy of the GNU General Public License
# along with this program; if not, see <http://www.gnu.org/licenses/>.

import cppimport
import numpy as np
import pybind11

import montblanc

cppimport.set_quiet(False)
mod = cppimport.imp("montblanc.util.casa_parangles")
mod = mod.util.casa_parangles

try:
import pyrap.measures

Expand Down Expand Up @@ -154,6 +160,25 @@ def _parallactic_angle_astropy(times, ap, fc):

import time

t = time.clock()
cangles = mod.parallactic_angles(ftimes, antenna_positions, phase_centre)
print 'cangles dones in %f' % (time.clock() - t)

t = time.time()
pa_astro = _parallactic_angle_astropy(ftimes, antenna_positions, phase_centre)
print "pa_astropy done in ", time.time() - t

t = time.clock()
pangles = parallactic_angles(ftimes, antenna_positions, phase_centre)
print 'pangles dones in %f' % (time.clock() - t)

assert np.allclose(cangles, pangles)

import sys
sys.exit(0)

import time

t = time.time()
pa_astro = _parallactic_angle_astropy(ftimes, antenna_positions, phase_centre)
print "pa_astropy done in ", time.time() - t
Expand Down
3 changes: 1 addition & 2 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -232,6 +232,5 @@ def include_pkg_dirs():
license='GPL2',
install_requires=install_requires,
packages=find_packages(),
package_data={'montblanc': include_pkg_dirs()},
include_package_data=True,
package_data={'montblanc': include_pkg_dirs() + [pjoin("util", "*.cpp")] },
zip_safe=False)

0 comments on commit b5a0421

Please sign in to comment.