7 #include "lsst/pex/exceptions.h"
12 namespace extensions {
13 namespace astrometryNet {
22 static time_t timer_callback(
void* baton) {
23 struct timer_baton* tt =
static_cast<struct timer_baton*
>(baton);
24 solver_t* solver = tt->s;
25 if (solver->timeused > tt->timelimit)
34 std::ostringstream os;
35 os <<
"Could not read multi-index star file " << filepath;
36 throw LSST_EXCEPT(lsst::pex::exceptions::RuntimeError, os.str());
41 int const flags = metadataOnly ? INDEX_ONLY_LOAD_METADATA : 0;
42 if (multiindex_add_index(_multiindex.get(), filepath.c_str(), flags)) {
43 std::ostringstream os;
44 os <<
"Failed to read multiindex from \"" << filepath <<
"\""
45 <<
" with meatadaOnly=" << metadataOnly;
46 throw LSST_EXCEPT(lsst::pex::exceptions::RuntimeError, os.str());
51 return index_is_within_range(multiindex_get(_multiindex.get(), 0), ra, dec, radius_deg);
55 if (multiindex_reload_starkd(_multiindex.get())) {
56 std::ostringstream os;
57 os <<
"Failed to reload multi-index star file " <<
getName();
58 throw LSST_EXCEPT(lsst::pex::exceptions::RuntimeError, os.str());
68 starxy_free(_solver->fieldxy);
69 _solver->fieldxy = NULL;
73 std::vector<index_t*> inds,
74 lsst::afw::coord::Coord
const &ctrCoord,
75 lsst::afw::geom::Angle
const &radius,
77 std::vector<std::string>
const& filterNameList,
78 std::vector<std::string>
const& magColList,
79 std::vector<std::string>
const& magErrColList,
80 const char* starGalCol,
84 if ((filterNameList.size() != magColList.size()) || (filterNameList.size() != magErrColList.size())) {
85 throw LSST_EXCEPT(lsst::pex::exceptions::InvalidParameterError,
86 "Filter name, mag column, and mag error column vectors must be the same length.");
88 std::vector<detail::MagColInfo> magColInfoList;
89 for (
size_t i=0; i<filterNameList.size(); ++i) {
94 magColInfoList.push_back(mc);
97 idCol, magColInfoList, starGalCol, varCol, uniqueIds);
102 auto qa = std::make_shared<daf::base::PropertyList>();
104 qa->set(
"meas_astrom*an*n_tried", _solver->numtries);
105 qa->set(
"meas_astrom*an*n_matched", _solver->nummatches);
106 qa->set(
"meas_astrom*an*n_scaleok", _solver->numscaleok);
107 qa->set(
"meas_astrom*an*n_cxdxcut", _solver->num_cxdx_skipped);
108 qa->set(
"meas_astrom*an*n_meanxcut", _solver->num_meanx_skipped);
109 qa->set(
"meas_astrom*an*n_radeccut", _solver->num_radec_skipped);
110 qa->set(
"meas_astrom*an*n_scalecut", _solver->num_abscale_skipped);
111 qa->set(
"meas_astrom*an*n_verified", _solver->num_verified);
112 qa->set(
"meas_astrom*an*time_used", _solver->timeused);
113 qa->set(
"meas_astrom*an*best_logodds", _solver->best_logodds);
114 if (_solver->best_index) {
115 index_t* ind = _solver->best_index;
116 qa->set(
"meas_astrom*an*best_index*id", ind->indexid);
117 qa->set(
"meas_astrom*an*best_index*hp", ind->healpix);
118 qa->set(
"meas_astrom*an*best_index*nside", ind->hpnside);
119 qa->set(
"meas_astrom*an*best_index*name", std::string(ind->indexname));
121 if (_solver->have_best_match) {
122 MatchObj* mo = &(_solver->best_match);
123 std::string
s = boost::str(boost::format(
"%i") % mo->star[0]);
124 for (
int i=1; i<mo->dimquads; i++)
125 s = s + boost::str(boost::format(
", %i") % mo->star[i]);
126 qa->set(
"meas_astrom*an*best_match*starinds", s);
127 qa->set(
"meas_astrom*an*best_match*coderr", std::sqrt(mo->code_err));
128 qa->set(
"meas_astrom*an*best_match*nmatch", mo->nmatch);
129 qa->set(
"meas_astrom*an*best_match*ndistract", mo->ndistractor);
130 qa->set(
"meas_astrom*an*best_match*nconflict", mo->nconflict);
131 qa->set(
"meas_astrom*an*best_match*nfield", mo->nfield);
132 qa->set(
"meas_astrom*an*best_match*nindex", mo->nindex);
133 qa->set(
"meas_astrom*an*best_match*nbest", mo->nbest);
134 qa->set(
"meas_astrom*an*best_match*logodds", mo->logodds);
135 qa->set(
"meas_astrom*an*best_match*parity", mo->parity ? 0 : 1);
136 qa->set(
"meas_astrom*an*best_match*nobjs", mo->objs_tried);
142 MatchObj* match = solver_get_best_match(_solver.get());
144 return std::shared_ptr<afw::image::Wcs>();
145 tan_t* wcs = &(match->wcstan);
147 afw::geom::Point2D crpix(wcs->crpix[0], wcs->crpix[1]);
148 std::shared_ptr<afw::coord::Coord const> crval
149 (
new afw::coord::Coord(wcs->crval[0] * afw::geom::degrees,
150 wcs->crval[1] * afw::geom::degrees));
151 return afw::image::makeWcs(*crval, crpix,
152 wcs->cd[0][0], wcs->cd[0][1],
153 wcs->cd[1][0], wcs->cd[1][1]);
157 solver_log_params(_solver.get());
158 struct timer_baton tt;
160 tt.s = _solver.get();
161 tt.timelimit = cpulimit;
162 _solver->userdata = &tt;
163 _solver->timer_callback = timer_callback;
165 solver_run(_solver.get());
167 _solver->timer_callback = NULL;
168 _solver->userdata = NULL;
179 for (std::vector<index_t*>::iterator pind = inds.begin();
180 pind != inds.end(); ++pind) {
183 if (_solver->use_radec) {
184 double ra,dec,radius;
185 xyzarr2radecdeg(_solver->centerxyz, &ra, &dec);
186 radius = distsq2deg(_solver->r2);
187 if (!index_is_within_range(man.
index, ra, dec, radius)) {
194 solver_get_quad_size_range_arcsec(_solver.get(), &qlo, &qhi);
195 if (!index_overlaps_scale_range(man.
index, qlo, qhi)) {
200 if (index_reload(man.
index)) {
201 throw LSST_EXCEPT(lsst::pex::exceptions::IoError,
202 "Failed to index_reload() an astrometry_net_data index file -- out of file descriptors?");
205 solver_add_index(_solver.get(), man.
index);
210 solver_set_field_bounds(_solver.get(), 0, width, 0, height);
211 double hi = hypot(width, height);
212 double lo = 0.1 * std::min(width, height);
213 solver_set_quad_size_range(_solver.get(), lo, hi);
218 starxy_free(_solver->fieldxy);
219 const size_t N = srcs.size();
220 starxy_t *starxy = starxy_new(N,
true,
false);
221 for (
size_t i=0; i<N; ++i) {
222 double const x = srcs[i].getX();
223 double const y = srcs[i].getY();
224 double const flux = srcs[i].getPsfFlux();
225 starxy_set(starxy, i, x - x0, y - y0);
226 starxy_set_flux(starxy, i, flux);
229 starxy_sort_by_flux(starxy);
231 starxy_free(solver_get_field(_solver.get()));
232 solver_free_field(_solver.get());
233 solver_set_field(_solver.get(), starxy);
234 solver_reset_field_size(_solver.get());
236 solver_preprocess_field(_solver.get());
240 lsst::afw::geom::Angle
healpixDistance(
int hp,
int nside, lsst::afw::coord::Coord
const& coord) {
241 lsst::afw::coord::IcrsCoord icrs = coord.toIcrs();
242 return lsst::afw::geom::Angle(healpix_distance_to_radec(hp, nside, icrs.getLongitude().asDegrees(),
243 icrs.getLatitude().asDegrees(), NULL),
244 lsst::afw::geom::degrees);
std::string magCol
name of magnitude column
std::string magErrCol
name of magnitude sigma column
std::string getName() const
MultiIndex(std::string const &filepath)
Construct a MultiIndex from an astrometry.net multi-index file.
void run(double cpulimit)
lsst::afw::table::SimpleCatalog getCatalogImpl(std::vector< index_t * > inds, lsst::afw::coord::Coord const &ctrCoord, lsst::afw::geom::Angle const &radius, const char *idCol, std::vector< MagColInfo > const &magColInfoList, const char *starGalCol, const char *varCol, bool uniqueIds=true)
Implementation for index_t::getCatalog method.
void setImageSize(int width, int height)
RAII manager for astrometry.net indices.
void addIndices(std::vector< index_t * > inds)
Add indices to the solver.
void addIndex(std::string const &filepath, bool metadataOnly)
Add an index read from a file.
std::string filterName
name of filter
lsst::afw::table::SimpleCatalog getCatalog(std::vector< index_t * > inds, lsst::afw::coord::Coord const &ctrCoord, lsst::afw::geom::Angle const &radius, const char *idCol, std::vector< std::string > const &filterNameList, std::vector< std::string > const &magColList, std::vector< std::string > const &magErrColList, const char *starGalCol, const char *varCol, bool uniqueIds=true)
Load reference objects in a region of the sky described by a center coordinate and a radius...
std::shared_ptr< lsst::daf::base::PropertyList > getSolveStats() const
lsst::afw::geom::Angle healpixDistance(int hp, int nside, lsst::afw::coord::Coord const &coord)
Calculate the distance from coordinates to a healpix.
std::shared_ptr< lsst::afw::image::Wcs > getWcs()
void setStars(lsst::afw::table::SourceCatalog const &srcs, int x0, int y0)
void reload()
Reload the indices.
int isWithinRange(double ra, double dec, double radius_deg)
Is this multi-index in range of the specified cone?