69 auto ccdImage = std::make_shared<CcdImage>(catalog, wcs,
visitInfo,
bbox, filter, photoCalib, detector,
78 centers.
push_back(ccdImage->getBoresightRaDec());
86 _commonTangentPoint =
Point(commonTangentPoint.getX(), commonTangentPoint.getY());
87 for (
auto &ccdImage :
ccdImageList) ccdImage->setCommonTangentPoint(_commonTangentPoint);
92 Frame tangentPlaneFrame;
95 Frame CTPFrame = ccdImage->getPixelToCommonTangentPlane()->apply(ccdImage->getImageFrame(),
false);
96 if (tangentPlaneFrame.
getArea() == 0)
97 tangentPlaneFrame = CTPFrame;
99 tangentPlaneFrame += CTPFrame;
104 TanPixelToRaDec commonTangentPlaneToRaDec(identity, _commonTangentPoint);
105 Frame raDecFrame = commonTangentPlaneToRaDec.
apply(tangentPlaneFrame,
false);
111 LOGLS_INFO(_log,
"Computed tangent plane box for data (degrees): " << raDecFrame);
121 const bool enlargeFittedList) {
127 item->clearBeforeAssoc();
137 ccdImage->resetCatalogForFit();
143 Frame ccdImageFrameCPT = toCommonTangentPlane->apply(ccdImage->getImageFrame(),
false);
144 ccdImageFrameCPT = ccdImageFrameCPT.
rescale(1.10);
150 if (ccdImageFrameCPT.
inFrame(*fittedStar)) {
157 toCommonTangentPlane.
get(), matchCutInArcSec / 3600.);
160 LOGLS_DEBUG(_log,
"Measured-to-Fitted matches before removing ambiguities " << starMatchList->size());
161 starMatchList->removeAmbiguities(*toCommonTangentPlane);
162 LOGLS_DEBUG(_log,
"Measured-to-Fitted matches after removing ambiguities " << starMatchList->size());
166 int matchedCount = 0;
167 for (
auto const &starMatch : *starMatchList) {
168 auto bs = starMatch.s1;
169 auto ms_const = std::dynamic_pointer_cast<const MeasuredStar>(bs);
170 auto ms = std::const_pointer_cast<MeasuredStar>(ms_const);
171 auto bs2 = starMatch.s2;
172 auto fs_const = std::dynamic_pointer_cast<const FittedStar>(bs2);
173 auto fs = std::const_pointer_cast<FittedStar>(fs_const);
174 ms->setFittedStar(fs);
177 LOGLS_DEBUG(_log,
"Matched " << matchedCount <<
" objects in " << ccdImage->getName());
180 int unMatchedCount = 0;
181 for (
auto const &mstar : catalog) {
183 if (mstar->getFittedStar())
continue;
184 if (enlargeFittedList) {
185 auto fs = std::make_shared<FittedStar>(*mstar);
187 toCommonTangentPlane->transformPosAndErrors(*fs, *fs);
189 mstar->setFittedStar(fs);
193 LOGLS_DEBUG(_log,
"Unmatched objects: " << unMatchedCount);
205 std::string const &fluxField,
float refCoordinateErr,
206 bool rejectBadFluxes) {
207 if (refCat.size() == 0) {
209 " reference catalog is empty : stop here "));
217 raErrKey = refCat.getSchema()[
"coord_raErr"];
218 decErrKey = refCat.getSchema()[
"coord_decErr"];
221 auto fluxKey = refCat.getSchema().find<
double>(fluxField).key;
225 fluxErrKey = refCat.getSchema().find<
double>(fluxField +
"Err").key;
228 << fluxField <<
"Err"
229 <<
") not found in reference catalog. Not using ref flux errors.");
236 pmRaKey = refCat.getSchema().find<
geom::Angle>(
"pm_ra").key;
237 pmDecKey = refCat.getSchema().find<
geom::Angle>(
"pm_dec").key;
239 LOGLS_WARN(_log,
"Not loading proper motions: (pm_ra,pm_dec) fields not found in reference catalog.");
241 LOGLS_WARN(_log,
"Not loading proper motions: RA/Dec proper motion values must be `geom:Angle`: "
245 pmRaErrKey = refCat.getSchema().find<
float>(
"pm_raErr").key;
246 pmDecErrKey = refCat.getSchema().find<
float>(
"pm_decErr").key;
248 LOGLS_WARN(_log,
"Not loading proper motions: error fields not available: " <<
ex.what());
253 pmRaDecCovKey = refCat.getSchema().find<
float>(
"pm_ra_pm_dec_Cov").key;
255 LOGLS_WARN(_log,
"No ra/dec proper motion covariances in refcat: " <<
ex.what());
259 for (
size_t i = 0; i < refCat.size(); i++) {
260 auto const &record = refCat.get(i);
262 auto coord = record->get(coordKey);
263 double flux = record->get(fluxKey);
265 if (fluxErrKey.isValid()) {
266 fluxErr = record->get(fluxErrKey);
272 auto star = std::make_shared<RefStar>(ra,
dec, flux, fluxErr);
280 star->vx =
std::pow(refCoordinateErr / 1000. / 3600. /
std::cos(coord.getLatitude()), 2);
281 star->vy =
std::pow(refCoordinateErr / 1000. / 3600., 2);
284 if (pmRaKey.isValid()) {
285 if (pmRaDecCovKey.isValid()) {
286 star->setProperMotion(std::make_unique<ProperMotion const>(
287 record->get(pmRaKey).asRadians(), record->get(pmDecKey).asRadians(),
288 record->get(pmRaErrKey), record->get(pmDecErrKey), record->get(pmRaDecCovKey)));
290 star->setProperMotion(std::make_unique<ProperMotion const>(
291 record->get(pmRaKey).asRadians(), record->get(pmDecKey).asRadians(),
292 record->get(pmRaErrKey), record->get(pmDecErrKey)));
306 TanRaDecToPixel raDecToCommonTangentPlane(identity, _commonTangentPoint);
308 associateRefStars(matchCut.
asArcseconds(), &raDecToCommonTangentPlane);
311void Associations::associateRefStars(
double matchCutInArcSec,
const AstrometryTransform *transform) {
315 matchCutInArcSec / 3600.);
317 LOGLS_DEBUG(_log,
"Refcat matches before removing ambiguities " << starMatchList->size());
318 starMatchList->removeAmbiguities(*transform);
319 LOGLS_DEBUG(_log,
"Refcat matches after removing ambiguities " << starMatchList->size());
322 for (
auto const &starMatch : *starMatchList) {
324 const auto &rs_const =
dynamic_cast<const RefStar &
>(bs);
325 auto &rs =
const_cast<RefStar &
>(rs_const);
326 const BaseStar &bs2 = *starMatch.s2;
327 const auto &fs_const =
dynamic_cast<const FittedStar &
>(bs2);
328 auto &fs =
const_cast<FittedStar &
>(fs_const);
334 "Associated " << starMatchList->size() <<
" reference stars among " <<
refStarList.
size());
338 selectFittedStars(minMeasurements);
339 normalizeFittedStars();
342void Associations::selectFittedStars(
int minMeasurements) {
345 int totalMeasured = 0, validMeasured = 0;
351 for (
auto mi = catalog.begin(); mi != catalog.end();) {
357 if (fittedStar ==
nullptr) {
364 if (!fittedStar->getRefStar() && fittedStar->getMeasurementCount() < minMeasurements) {
365 fittedStar->getMeasurementCount()--;
366 mi = catalog.erase(mi);
376 if ((*fi)->getMeasurementCount() == 0) {
384 LOGLS_INFO(_log,
"Total, valid number of Measured stars: " << totalMeasured <<
", " << validMeasured);
387void Associations::normalizeFittedStars() {
392 fittedStar->setFlux(0.0);
393 fittedStar->getMag() = 0.0;
399 MeasuredStarList &catalog = ccdImage->getCatalogForFit();
400 for (
auto &mi : catalog) {
401 auto fittedStar =
mi->getFittedStar();
402 if (fittedStar ==
nullptr)
404 pex::exceptions::RuntimeError,
405 "All measuredStars must have a fittedStar: did you call selectFittedStars()?"));
406 auto point = toCommonTangentPlane->apply(*mi);
407 fittedStar->x += point.x;
408 fittedStar->y += point.y;
409 fittedStar->getFlux() +=
mi->getFlux();
413 _maxMeasuredStars = 0;
415 auto measurementCount = fi->getMeasurementCount();
416 _maxMeasuredStars += measurementCount;
417 fi->x /= measurementCount;
418 fi->y /= measurementCount;
419 fi->getFlux() /= measurementCount;
428 while (iter !=
end) {
429 auto fittedStar = *iter;
430 if (fittedStar->getMeasurementCount() == 0) {
431 LOGLS_TRACE(_log,
"Deleting FittedStar (has no measuredStars): " << *fittedStar);
439 LOGLS_INFO(_log,
"Removed " <<
count <<
" fittedStars that had no associated measuredStar.");
443void Associations::assignMags() {
446 for (
auto const &mstar : catalog) {
448 if (!fstar)
continue;
459 "DeprojectFittedStars: Fitted stars are already in sidereal coordinates, nothing done ");
470 return item->getCatalogForFit().size() > 0;
477 if ((fittedStar !=
nullptr) && (fittedStar->getRefStar() !=
nullptr))
count++;
483void Associations::collectMCStars(
int realization) {
489 string dbimdir = ccdImage.Dir();
490 string mctruth = dbimdir +
"/mc/mctruth.list";
492 if (realization >= 0) {
494 sstrm << dbimdir <<
"/mc/mctruth_" << realization <<
".list";
495 mctruth = sstrm.
str();
498 AstrometryTransformIdentity gti;
502 DicStarList mctruthlist(mctruth);
506 for (smI = starMatchList->begin(); smI != starMatchList->end(); smI++) {
507 StarMatch &sm = *smI;
508 BaseStar *bs = sm.s1;
509 MeasuredStar *mstar =
dynamic_cast<MeasuredStar *
>(bs);
511 DicStar *dstar =
dynamic_cast<DicStar *
>(bs);
513 mcstar->GetMCInfo().iflux = dstar->getval(
"iflux");
514 mcstar->GetMCInfo().tflux = dstar->getval(
"sflux");
521 LOGLS_FATAL(_log,
"CollectMCStars Unable to match MCTruth w/ catalog!");
This file declares a class for representing circular regions on the unit sphere.
This file declares a class for representing convex polygons with great circle edges on the unit spher...
#define LSST_EXCEPT(type,...)
Create an exception with a given type.
Combinatorial searches for linear transformations to go from list1 to list2.
LSST DM logging module built on log4cxx.
#define LOGLS_WARN(logger, message)
Log a warn-level message using an iostream-based interface.
#define LOGLS_FATAL(logger, message)
Log a fatal-level message using an iostream-based interface.
#define LOG_GET(logger)
Returns a Log object associated with logger.
#define LOGLS_INFO(logger, message)
Log a info-level message using an iostream-based interface.
#define LOGLS_DEBUG(logger, message)
Log a debug-level message using an iostream-based interface.
#define LOGLS_TRACE(logger, message)
Log a trace-level message using an iostream-based interface.
This file contains a class representing spherical coordinates.
Tag types used to declare specialized field types.
A FunctorKey used to get or set celestial coordinates from a pair of lsst::geom::Angle keys.
Custom catalog class for record/table subclasses that are guaranteed to have an ID,...
A class representing an angle.
constexpr double asArcseconds() const noexcept
Return an Angle's value in arcseconds.
An integer coordinate rectangle.
size_t nFittedStarsWithAssociatedRefStar() const
Return the number of fittedStars that have an associated refStar.
void cleanFittedStars()
Remove FittedStars that have no measured stars; this can happen after outlier rejection.
void computeCommonTangentPoint()
Sets a shared tangent point for all ccdImages, using the mean of the centers of all ccdImages.
lsst::sphgeom::Circle computeBoundingCircle() const
Return the bounding circle in on-sky (RA, Dec) coordinates containing all CcdImages.
int nCcdImagesValidForFit() const
return the number of CcdImages with non-empty catalogs to-be-fit.
void createCcdImage(afw::table::SourceCatalog &catalog, const std::shared_ptr< lsst::afw::geom::SkyWcs > &wcs, const std::shared_ptr< lsst::afw::image::VisitInfo > &visitInfo, const lsst::geom::Box2I &bbox, const std::string &filter, const std::shared_ptr< afw::image::PhotoCalib > &photoCalib, const std::shared_ptr< afw::cameraGeom::Detector > &detector, int visit, int ccd, const lsst::jointcal::JointcalControl &control)
Create a ccdImage from an exposure catalog and metadata, and add it to the list.
void associateCatalogs(double matchCutInArcsec=0, bool useFittedList=false, bool enlargeFittedList=true)
incrementaly builds a merged catalog of all image catalogs
void setCommonTangentPoint(lsst::geom::Point2D const &commonTangentPoint)
Shared tangent point for all ccdImages (decimal degrees).
Point getCommonTangentPoint() const
Shared tangent point for all ccdImages (decimal degrees).
void collectRefStars(afw::table::SimpleCatalog &refCat, geom::Angle matchCut, std::string const &fluxField, float refCoordinateErr, bool rejectBadFluxes=false)
Collect stars from an external reference catalog and associate them with fittedStars.
CcdImageList ccdImageList
FittedStarList fittedStarList
void prepareFittedStars(int minMeasurements)
Prepare the fittedStar list by making quality cuts and normalizing measurements.
void deprojectFittedStars()
Sends back the fitted stars coordinates on the sky FittedStarsList::inTangentPlaneCoordinates keeps t...
The base class for handling stars. Used by all matching routines.
Handler of an actual image from a single CCD.
MeasuredStarList const & getCatalogForFit() const
Gets the catalog to be used for fitting, which may have been cleaned-up.
FittedStars are objects whose position or flux is going to be fitted, and which come from the associa...
void setRefStar(const RefStar *_refStar)
Set the astrometric reference star associated with this star.
A list of FittedStar s. Such a list is typically constructed by Associations.
bool inTangentPlaneCoordinates
rectangle with sides parallel to axes.
bool inFrame(double x, double y) const
inside?
double xMin
coordinate of boundary.
Frame rescale(double factor) const
rescale it. The center does not move.
Sources measured on images.
std::shared_ptr< FittedStar > getFittedStar() const
double getMagWeight() const
the inverse of the mag variance
A list of MeasuredStar. They are usually filled in Associations::createCcdImage.
Objects used as position/flux anchors (e.g.
void applyTransform(const Operator &op)
enables to apply a geometrical transform if Star is Basestar or derives from it.
The transformation that handles pixels to sideral transformations (Gnomonic, possibly with polynomial...
virtual void apply(double xIn, double yIn, double &xOut, double &yOut) const=0
Transform pixels to ICRS RA, Dec in degrees.
This one is the Tangent Plane (called gnomonic) projection (from celestial sphere to tangent plane)
Reports invalid arguments.
Reports attempts to access elements using an invalid key.
Reports errors from accepting an object of an unexpected or inappropriate type.
Circle is a circular region on the unit sphere that contains its boundary.
static ConvexPolygon convexHull(std::vector< UnitVector3d > const &points)
convexHull returns the convex hull of the given set of points if it exists and throws an exception ot...
Circle getBoundingCircle() const override
getBoundingCircle returns a bounding-circle for this region.
static LonLat fromDegrees(double lon, double lat)
T emplace_back(T... args)
double nanojanskyToABMagnitude(double flux)
Convert a flux in nanojansky to AB magnitude.
SpherePoint averageSpherePoint(std::vector< SpherePoint > const &coords)
Return the average of a list of coordinates.
AngleUnit constexpr degrees
constant with units of degrees
constexpr double radToDeg(double x) noexcept
BaseStarList & Measured2Base(MeasuredStarList &This)
BaseStarList & Fitted2Base(FittedStarList &This)
std::unique_ptr< StarMatchList > listMatchCollect(const BaseStarList &list1, const BaseStarList &list2, const AstrometryTransform *guess, double maxDist)
assembles star matches.
::std::list< StarMatch >::iterator StarMatchIterator
BaseStarList & Ref2Base(RefStarList &This)
std::string sourceFluxField
"name of flux field in source catalog" ;