72 size_t const nMag = magColInfoList.size();
74 for (
auto mc = magColInfoList.cbegin(); mc != magColInfoList.cend(); ++mc) {
75 if (mc->filterName.empty()) {
76 throw LSST_EXCEPT(lsst::pex::exceptions::InvalidParameterError,
77 "Magnitude names cannot be empty strings.");
81 if (mc->magCol.empty()) {
82 throw LSST_EXCEPT(lsst::pex::exceptions::InvalidParameterError,
83 "Magnitude column names cannot be empty strings.");
88 auto icrsCoord = ctrCoord.toIcrs();
89 double raDeg = icrsCoord.getLongitude().asDegrees();
90 double decDeg = icrsCoord.getLatitude().asDegrees();
92 radecdeg2xyzarr(raDeg, decDeg, xyz);
93 double r2 = deg2distsq(radius.asDegrees());
97 afw::table::PointKey<double>::addFields(schema,
"centroid",
98 "centroid on some exposure; invalid unless \"hasCentroid\" is true)",
"pixels");
99 auto hasCentroidKey = schema.addField<afwTable::Flag>(
"hasCentroid",
100 "true if centroid field has been set");
102 std::vector<afwTable::Key<double> > fluxKey;
103 std::vector<afwTable::Key<double> > fluxErrKey;
104 fluxKey.reserve(nMag);
105 fluxErrKey.reserve(nMag);
107 for (
auto mc = magColInfoList.cbegin(); mc != magColInfoList.cend(); ++mc) {
111 schema.addField<
double>(
112 mc->filterName +
"_flux",
113 mc->filterName +
" flux"));
115 fluxErrKey.push_back(
116 schema.addField<
double>(
117 mc->filterName +
"_fluxSigma",
118 mc->filterName +
" flux uncertainty (sigma)"));
124 resolvedKey = schema.addField<afwTable::Flag>(
126 "set if the reference object is resolved");
130 variableKey = schema.addField<afwTable::Flag>(
132 "set if the reference object is variable");
136 "set if the reference object can be used in photometric calibration");
148 std::set<boost::int64_t> uids;
150 for (std::vector<index_t*>::iterator pind = inds.begin(); pind != inds.end(); ++pind) {
151 index_t* ind = (*pind);
153 double *radecs = NULL;
154 int *starinds = NULL;
156 startree_search_for(ind->starkd, xyz, r2, NULL, &radecs, &starinds, &nstars);
162 std::vector<float*> mag;
163 std::vector<float*> magErr;
165 magErr.reserve(nMag);
166 boost::int64_t*
id = NULL;
167 bool* stargal = NULL;
169 if (idCol || nMag || isStarCol || isVarCol) {
170 fitstable_t* tag = startree_get_tagalong(ind->starkd);
171 tfits_type flt = fitscolumn_float_type();
172 tfits_type boo = fitscolumn_boolean_type();
173 tfits_type i64 = fitscolumn_i64_type();
177 "astrometry_net_data index file %s does not contain a tag-along table, "
178 "so can't retrieve extra columns. idCol=%s, isStarCol=%s, isVarCol=%s") %
179 ind->indexname % idCol % isStarCol % isVarCol);
180 msg +=
", mag columns=[";
181 for (
unsigned int i=0; i<nMag; i++) {
185 msg +=
" name='" + magColInfoList[i].filterName +
186 "', mag='" + magColInfoList[i].magCol +
187 "', magErr='" + magColInfoList[i].magErrCol +
"'";
189 msg +=
" ]. You may need to edit the $ASTROMETRY_NET_DATA_DIR/andConfig.py file to set idColumn=None, etc.";
190 throw LSST_EXCEPT(lsst::pex::exceptions::NotFoundError, msg);
194 id =
static_cast<int64_t*
>(fitstable_read_column_inds(tag, idCol, i64, starinds, nstars));
196 throw LSST_EXCEPT(lsst::pex::exceptions::NotFoundError,
197 str(
boost::format(
"Unable to read data for %s from %s") % idCol % ind->indexname));
200 if (
id && uniqueIds) {
207 uids = std::set<boost::int64_t>(
id,
id+nstars);
210 for (
int i=0; i<nstars; i++) {
212 if (uids.insert(
id[i]).second) {
216 starinds[nkeep] = starinds[i];
217 radecs[nkeep*2+0] = radecs[i*2+0];
218 radecs[nkeep*2+1] = radecs[i*2+1];
238 for (
auto mc = magColInfoList.cbegin(); mc != magColInfoList.cend(); ++mc) {
239 char const*
col = mc->magCol.c_str();
240 mag.push_back(read_column(tag, col, flt, starinds, nstars, ind->indexname));
242 char const* col = mc->magErrCol.c_str();
243 magErr.push_back(read_column(tag, col, flt, starinds, nstars, ind->indexname));
253 uint8_t* sg =
static_cast<uint8_t*
>(fitstable_read_column_inds(
254 tag, isStarCol, fitscolumn_u8_type(), starinds, nstars));
255 stargal =
static_cast<bool*
>(malloc(nstars));
257 throw LSST_EXCEPT(lsst::pex::exceptions::NotFoundError,
258 str(
boost::format(
"Unable to read data for %s from %s") % isStarCol % ind->indexname));
260 for (
int j=0; j<nstars; j++) {
261 stargal[j] = (sg[j] > 0);
266 var =
static_cast<bool*
>(fitstable_read_column_inds(tag, isVarCol, boo, starinds, nstars));
268 throw LSST_EXCEPT(lsst::pex::exceptions::NotFoundError,
269 str(
boost::format(
"Unable to read data for %s from %s") % isVarCol % ind->indexname));
274 for (
int i=0; i<nstars; i++) {
281 radecs[i * 2 + 0] * afwGeom::
degrees,
282 radecs[i * 2 + 1] * afwGeom::degrees
290 src->set(hasCentroidKey,
false);
292 assert(fluxKey.size() == nMag);
294 assert(fluxErrKey.size() == magErr.size());
298 for (
auto mc = magColInfoList.cbegin(); mc != magColInfoList.cend(); ++mc, ++j) {
306 src->set(fluxKey[j], flux);
311 src->set(fluxErrKey[ej], fluxErr);
315 assert(ej == fluxErrKey.size());
317 bool photometric =
true;
319 src->set(resolvedKey, !stargal[i]);
320 photometric &= stargal[i];
323 src->set(variableKey, var[i]);
324 photometric &= (!var[i]);
326 src->set(photometricKey, photometric);
330 for (
size_t j=0; j<mag.size(); ++j) {
333 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.
afw::table::Schema schema
double fluxErrFromABMagErr(double magErr, double mag)
Compute flux error in Janskys from AB magnitude error and AB magnitude.
double fluxFromABMag(double mag)
Compute flux in Janskys from AB magnitude.
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
if(width!=gim.getWidth()||height!=gim.getHeight()||x0!=gim.getX0()||y0!=gim.getY0())
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