73 size_t const nMag = magcols.size();
74 std::vector<mag_column_t>::const_iterator mc;
76 for (mc = magcols.begin(); mc != magcols.end(); ++mc) {
77 if (mc->name.size() == 0) {
78 throw LSST_EXCEPT(lsst::pex::exceptions::InvalidParameterError,
79 "Magnitude names cannot be empty strings.");
83 if (mc->magcol.size() == 0) {
84 throw LSST_EXCEPT(lsst::pex::exceptions::InvalidParameterError,
85 "Magnitude column names cannot be empty string.");
91 radecdeg2xyzarr(ra, dec, xyz);
92 double r2 = deg2distsq(radius);
95 std::vector<afwTable::Key<double> > fluxKey;
96 std::vector<afwTable::Key<double> > fluxErrKey;
97 fluxKey.reserve(nMag);
98 fluxErrKey.reserve(nMag);
100 for (mc = magcols.begin(); mc != magcols.end(); ++mc) {
103 std::string comment = (mc->name ==
"flux" ?
"flux" : mc->name + std::string(
" flux"));
104 fluxKey.push_back(schema.
addField<
double>(mc->name, comment));
106 std::string comment = (mc->name ==
"flux" ?
"flux uncertainty" : mc->name + std::string(
" flux uncertainty"));
107 fluxErrKey.push_back(schema.
addField<
double>(mc->name +
".err", comment));
113 stargalKey = schema.
addField<afwTable::Flag>(
114 "stargal",
"set if the reference object is a star");
118 varKey = schema.
addField<afwTable::Flag>(
"var",
"set if the reference object is variable");
121 "photometric",
"set if the reference object can be used in photometric calibration"
134 std::set<boost::int64_t> uids;
136 for (std::vector<index_t*>::iterator pind = inds.begin();
137 pind != inds.end(); ++pind) {
139 index_t* ind = (*pind);
141 double *radecs = NULL;
142 int *starinds = NULL;
144 startree_search_for(ind->starkd, xyz, r2, NULL,
145 &radecs, &starinds, &nstars);
151 std::vector<float*> mag;
152 std::vector<float*> magerr;
154 magerr.reserve(nMag);
155 boost::int64_t*
id = NULL;
156 bool* stargal = NULL;
158 if (idcol || nMag || stargalcol || varcol) {
159 fitstable_t* tag = startree_get_tagalong(ind->starkd);
160 tfits_type flt = fitscolumn_float_type();
161 tfits_type boo = fitscolumn_boolean_type();
162 tfits_type i64 = fitscolumn_i64_type();
165 std::string msg = boost::str(
boost::format(
"astrometry_net_data index file %s does not contain a tag-along table, "
166 "so can't retrieve extra columns. idcol=%s, stargalcol=%s, varcol=%s") %
167 ind->indexname % idcol % stargalcol % varcol);
168 msg +=
", mag columns=[";
169 for (
unsigned int i=0; i<nMag; i++) {
173 msg +=
" name='" + magcols[i].name +
174 "', mag='" + magcols[i].magcol +
175 "', magerr='" + magcols[i].magerrcol +
"'";
177 msg +=
" ]. You may need to edit the $ASTROMETRY_NET_DATA_DIR/andConfig.py file to set idColumn=None, etc.";
178 throw LSST_EXCEPT(lsst::pex::exceptions::NotFoundError, msg);
182 id =
static_cast<int64_t*
>(fitstable_read_column_inds(tag, idcol, i64, starinds, nstars));
184 throw LSST_EXCEPT(lsst::pex::exceptions::NotFoundError,
186 idcol % ind->indexname));
189 if (
id && unique_ids) {
196 uids = std::set<boost::int64_t>(
id,
id+nstars);
199 for (
int i=0; i<nstars; i++) {
201 if (uids.insert(
id[i]).second) {
205 starinds[nkeep] = starinds[i];
206 radecs[nkeep*2+0] = radecs[i*2+0];
207 radecs[nkeep*2+1] = radecs[i*2+1];
227 for (mc = magcols.begin(); mc != magcols.end(); ++mc) {
228 char const*
col = mc->magcol.c_str();
229 mag.push_back(read_column(tag, col, flt, starinds, nstars, ind->indexname));
231 char const* col = mc->magerrcol.c_str();
232 magerr.push_back(read_column(tag, col, flt, starinds, nstars, ind->indexname));
242 uint8_t* sg =
static_cast<uint8_t*
>(fitstable_read_column_inds(tag, stargalcol, fitscolumn_u8_type(), starinds, nstars));
243 stargal =
static_cast<bool*
>(malloc(nstars));
245 throw LSST_EXCEPT(lsst::pex::exceptions::NotFoundError,
247 stargalcol % ind->indexname));
249 for (
int j=0; j<nstars; j++) {
250 stargal[j] = (sg[j] > 0);
255 var =
static_cast<bool*
>(fitstable_read_column_inds(tag, varcol, boo, starinds, nstars));
257 throw LSST_EXCEPT(lsst::pex::exceptions::NotFoundError,
259 varcol % ind->indexname));
264 for (
int i=0; i<nstars; i++) {
271 radecs[i * 2 + 0] * afwGeom::
degrees,
272 radecs[i * 2 + 1] * afwGeom::degrees
280 assert(fluxKey.size() == nMag);
282 assert(fluxErrKey.size() == magerr.size());
286 for (mc = magcols.begin(); mc != magcols.end(); ++mc, ++j) {
294 double flux = pow(10.0, -0.4*mag[j][i]);
296 src->set(fluxKey[j], flux);
299 double fluxerr = fabs(-0.4*magerr[ej][i]*flux*std::log(10.0));
301 src->set(fluxErrKey[ej], fluxerr);
305 assert(ej == fluxErrKey.size());
309 src->set(stargalKey, stargal[i]);
313 src->set(varKey, var[i]);
316 src->set(photometricKey, ok);
320 for (
size_t j=0; j<mag.size(); ++j) {
323 for (
size_t j=0; j<magerr.size(); ++j) {
Defines the fields and offsets for a table.
static Schema makeMinimalSchema()
Return a minimal schema for Simple tables and records.
Key< T > addField(Field< T > const &field, bool doReplace=false)
Add a new field to the Schema, and return the associated Key.
Custom catalog class for record/table subclasses that are guaranteed to have an ID, and should generally be sorted by that ID.
lsst::afw::coord::IcrsCoord IcrsCoord
A polymorphic functor base class for generating record IDs for a table.
#define LSST_EXCEPT(type,...)
A class used as a handle to a particular field in a table.
static boost::shared_ptr< SimpleTable > make(Schema const &schema, boost::shared_ptr< IdFactory > const &idFactory)
Construct a new table.
Record class that must contain a unique ID field and a celestial coordinate field.
SortedCatalogT< SimpleRecord > SimpleCatalog