56 LOG_LOGGER _log =
LOG_GET(
"jointcal.Associations");
69 auto ccdImage = std::make_shared<CcdImage>(catalog, wcs, visitInfo, bbox, filter, photoCalib, detector,
78 centers.
reserve(ccdImageList.size());
79 for (
auto const &
ccdImage : ccdImageList) {
82 auto commonTangentPoint = geom::averageSpherePoint(centers);
83 LOGLS_DEBUG(_log,
"Using common tangent point: " << commonTangentPoint.getPosition(geom::degrees));
84 setCommonTangentPoint(commonTangentPoint.getPosition(geom::degrees));
88 _commonTangentPoint =
Point(commonTangentPoint.getX(), commonTangentPoint.getY());
89 for (
auto &
ccdImage : ccdImageList)
ccdImage->setCommonTangentPoint(_commonTangentPoint);
94 Frame tangentPlaneFrame;
96 for (
auto const &
ccdImage : ccdImageList) {
98 if (tangentPlaneFrame.
getArea() == 0)
99 tangentPlaneFrame = CTPFrame;
101 tangentPlaneFrame += CTPFrame;
106 TanPixelToRaDec commonTangentPlaneToRaDec(identity, _commonTangentPoint);
107 Frame raDecFrame = commonTangentPlaneToRaDec.
apply(tangentPlaneFrame,
false);
118 return sphgeom::ConvexPolygon::convexHull(points).getBoundingCircle();
122 const bool enlargeFittedList) {
127 for (
auto &item : fittedStarList) {
128 item->clearBeforeAssoc();
131 if (!useFittedList) fittedStarList.clear();
133 for (
auto &
ccdImage : ccdImageList) {
144 Frame ccdImageFrameCPT = toCommonTangentPlane->apply(
ccdImage->getImageFrame(),
false);
145 ccdImageFrameCPT = ccdImageFrameCPT.
rescale(1.10);
150 for (
auto const &fittedStar : fittedStarList) {
151 if (ccdImageFrameCPT.
inFrame(*fittedStar)) {
158 toCommonTangentPlane.
get(), matchCutInArcSec / 3600.);
161 LOGLS_DEBUG(_log,
"Measured-to-Fitted matches before removing ambiguities " << starMatchList->size());
162 starMatchList->removeAmbiguities(*toCommonTangentPlane);
163 LOGLS_DEBUG(_log,
"Measured-to-Fitted matches after removing ambiguities " << starMatchList->size());
167 int matchedCount = 0;
168 for (
auto const &starMatch : *starMatchList) {
169 auto bs = starMatch.s1;
172 auto bs2 = starMatch.s2;
175 ms->setFittedStar(fs);
178 LOGLS_INFO(_log,
"Matched " << matchedCount <<
" objects in " <<
ccdImage->getName());
181 int unMatchedCount = 0;
182 for (
auto const &mstar : catalog) {
184 if (mstar->getFittedStar())
continue;
185 if (enlargeFittedList) {
186 auto fs = std::make_shared<FittedStar>(*mstar);
188 toCommonTangentPlane->transformPosAndErrors(*fs, *fs);
189 fittedStarList.push_back(fs);
190 mstar->setFittedStar(fs);
194 LOGLS_INFO(_log,
"Unmatched objects: " << unMatchedCount);
206 std::string const &fluxField,
float refCoordinateErr,
207 bool rejectBadFluxes) {
208 if (refCat.
size() == 0) {
210 " reference catalog is empty : stop here "));
218 raErrKey = refCat.
getSchema()[
"coord_raErr"];
219 decErrKey = refCat.
getSchema()[
"coord_decErr"];
229 << fluxField <<
"Err" 230 <<
") not found in reference catalog. Not using ref flux errors.");
234 for (
size_t i = 0; i < refCat.
size(); i++) {
235 auto const &record = refCat.
get(i);
237 auto coord = record->get(coordKey);
238 double flux = record->get(fluxKey);
240 if (fluxErrKey.isValid()) {
241 fluxErr = record->get(fluxErrKey);
247 auto star = std::make_shared<RefStar>(ra, dec, flux, fluxErr);
250 star->vx = record->get(raErrKey);
251 star->vy = record->get(decErrKey);
254 star->vx =
std::pow(refCoordinateErr / 1000. / 3600. /
std::cos(coord.getLatitude()), 2);
255 star->vy =
std::pow(refCoordinateErr / 1000. / 3600., 2);
262 refStarList.push_back(star);
267 TanRaDecToPixel raDecToCommonTangentPlane(identity, _commonTangentPoint);
269 associateRefStars(matchCut.
asArcseconds(), &raDecToCommonTangentPlane);
276 matchCutInArcSec / 3600.);
278 LOGLS_DEBUG(_log,
"Refcat matches before removing ambiguities " << starMatchList->size());
279 starMatchList->removeAmbiguities(*transform);
280 LOGLS_DEBUG(_log,
"Refcat matches after removing ambiguities " << starMatchList->size());
283 for (
auto const &starMatch : *starMatchList) {
287 const BaseStar &bs2 = *starMatch.s2;
295 "Associated " << starMatchList->size() <<
" reference stars among " << refStarList.size());
299 selectFittedStars(minMeasurements);
300 normalizeFittedStars();
303 void Associations::selectFittedStars(
int minMeasurements) {
304 LOGLS_INFO(_log,
"Fitted stars before measurement # cut: " << fittedStarList.size());
306 int totalMeasured = 0, validMeasured = 0;
309 for (
auto const &
ccdImage : ccdImageList) {
318 if (fittedStar ==
nullptr) {
325 if (!fittedStar->getRefStar() && fittedStar->getMeasurementCount() < minMeasurements) {
326 fittedStar->getMeasurementCount()--;
327 mi = catalog.
erase(mi);
337 if ((*fi)->getMeasurementCount() == 0) {
338 fi = fittedStarList.erase(fi);
344 LOGLS_INFO(_log,
"Fitted stars after measurement # cut: " << fittedStarList.size());
345 LOGLS_INFO(_log,
"Total, valid number of Measured stars: " << totalMeasured <<
", " << validMeasured);
348 void Associations::normalizeFittedStars()
const {
350 for (
auto &fittedStar : fittedStarList) {
353 fittedStar->setFlux(0.0);
354 fittedStar->getMag() = 0.0;
358 for (
auto const &
ccdImage : ccdImageList) {
361 for (
auto &mi : catalog) {
362 auto fittedStar = mi->getFittedStar();
363 if (fittedStar ==
nullptr)
366 "All measuredStars must have a fittedStar: did you call selectFittedStars()?"));
367 auto point = toCommonTangentPlane->apply(*mi);
368 fittedStar->x += point.x;
369 fittedStar->y += point.y;
370 fittedStar->getFlux() += mi->getFlux();
374 for (
auto &fi : fittedStarList) {
375 auto measurementCount = fi->getMeasurementCount();
376 fi->x /= measurementCount;
377 fi->y /= measurementCount;
378 fi->getFlux() /= measurementCount;
379 fi->getMag() = utils::nanojanskyToABMagnitude(fi->getFlux());
383 void Associations::assignMags() {
384 for (
auto const &
ccdImage : ccdImageList) {
386 for (
auto const &mstar : catalog) {
387 auto fstar = mstar->getFittedStar();
388 if (!fstar)
continue;
389 fstar->addMagMeasurement(mstar->getMag(), mstar->getMagWeight());
397 if (!fittedStarList.inTangentPlaneCoordinates) {
399 "DeprojectFittedStars: Fitted stars are already in sidereal coordinates, nothing done ");
404 fittedStarList.applyTransform(ctp2Sky);
405 fittedStarList.inTangentPlaneCoordinates =
false;
410 return item->getCatalogForFit().size() > 0;
416 for (
auto const &fittedStar : fittedStarList) {
417 if ((fittedStar !=
nullptr) & (fittedStar->getRefStar() !=
nullptr)) count++;
423 void Associations::collectMCStars(
int realization) {
427 for (I = ccdImageList.begin(); I != ccdImageList.end(); I++) {
429 string dbimdir = ccdImage.Dir();
430 string mctruth = dbimdir +
"/mc/mctruth.list";
432 if (realization >= 0) {
434 sstrm << dbimdir <<
"/mc/mctruth_" << realization <<
".list";
435 mctruth = sstrm.
str();
442 DicStarList mctruthlist(mctruth);
446 for (smI = starMatchList->begin(); smI != starMatchList->end(); smI++) {
451 DicStar *dstar =
dynamic_cast<DicStar *
>(bs);
453 mcstar->GetMCInfo().iflux = dstar->getval(
"iflux");
454 mcstar->GetMCInfo().tflux = dstar->getval(
"sflux");
461 LOGLS_FATAL(_log,
"CollectMCStars Unable to match MCTruth w/ catalog!");
466 double matchCutArcSec) {
468 size_t pos_minus = color.
find(
'-');
469 bool compute_diff = (pos_minus != string::npos);
471 c1 = color.
substr(0, pos_minus);
472 if (compute_diff) c2 = color.
substr(pos_minus + 1, string::npos);
473 DicStarList cList(dicStarListName);
474 if (!cList.HasKey(c1))
475 throw(GastroException(
"Associations::SetFittedstarColors : " + dicStarListName +
476 " misses a key named \"" + c1 +
"\""));
477 if (compute_diff && !cList.HasKey(c2))
478 throw(GastroException(
"Associations::SetFittedstarColors : " + dicStarListName +
479 " misses a key named \"" + c2 +
"\""));
487 if (fittedStarList.inTangentPlaneCoordinates) id_or_proj = &id;
492 id_or_proj, matchCutArcSec / 3600);
494 LOGLS_INFO(_log,
"Matched " << starMatchList->size() <<
'/' << fittedStarList.size()
495 <<
" FittedStars to color catalog");
497 for (
auto i = starMatchList->begin(); i != starMatchList->end(); ++i) {
501 const TStar *ts =
dynamic_cast<const TStar *
>(s2);
502 const DicStar *ds =
dynamic_cast<const DicStar *
>(ts->get_original());
503 fs->
color = ds->getval(c1);
504 if (compute_diff) fs->
color -= ds->getval(c2);
#define LOGLS_WARN(logger, message)
Objects used as position anchors, typically USNO stars.
The transformation that handles pixels to sideral transformations (Gnomonic, possibly with polynomial...
int nCcdImagesValidForFit() const
return the number of CcdImages with non-empty catalogs to-be-fit.
MeasuredStarList::iterator MeasuredStarIterator
A hanger for star associations.
constexpr double radToDeg(double x) noexcept
void apply(const double xIn, const double yIn, double &xOut, double &yOut) const
Transform pixels to ICRS RA, Dec in degrees.
double xMin
coordinate of boundary.
void createCcdImage(afw::table::SourceCatalog &catalog, std::shared_ptr< lsst::afw::geom::SkyWcs > wcs, std::shared_ptr< lsst::afw::image::VisitInfo > visitInfo, lsst::geom::Box2I const &bbox, std::string const &filter, std::shared_ptr< afw::image::PhotoCalib > photoCalib, std::shared_ptr< afw::cameraGeom::Detector > detector, int visit, int ccd, lsst::jointcal::JointcalControl const &control)
Create a ccdImage from an exposure catalog and metadata, and add it to the list.
std::unique_ptr< StarMatchList > listMatchCollect(const BaseStarList &list1, const BaseStarList &list2, const AstrometryTransform *guess, const double maxDist)
assembles star matches.
void associateCatalogs(const double matchCutInArcsec=0, const bool useFittedList=false, const bool enlargeFittedList=true)
incrementaly builds a merged catalog of all image catalogs
A list of MeasuredStar. They are usually filled in Associations::createCcdImage.
Frame rescale(const double factor) const
rescale it. The center does not move.
The base class for handling stars. Used by all matching routines.
void prepareFittedStars(int minMeasurements)
Set the color field of FittedStar 's from a colored catalog.
size_t nFittedStarsWithAssociatedRefStar() const
Return the number of fittedStars that have an associated refStar.
rectangle with sides parallel to axes.
#define LOGLS_DEBUG(logger, message)
SchemaItem< T > find(std::string const &name) const
Class for a simple mapping implementing a generic AstrometryTransform.
void setRefStar(const RefStar *_refStar)
Set the astrometric reference star associated with this star.
void computeCommonTangentPoint()
Sets a shared tangent point for all ccdImages, using the mean of the centers of all ccdImages...
FittedStarList::iterator FittedStarIterator
A list of FittedStar s. Such a list is typically constructed by Associations.
This one is the Tangent Plane (called gnomonic) projection (from celestial sphere to tangent plane) ...
objects measured on actual images.
T dynamic_pointer_cast(T... args)
::std::list< StarMatch >::iterator StarMatchIterator
void deprojectFittedStars()
Sends back the fitted stars coordinates on the sky FittedStarsList::inTangentPlaneCoordinates keeps t...
constexpr double asArcseconds() const noexcept
#define LOGLS_INFO(logger, message)
bool inFrame(double x, double y) const
inside?
#define LSST_EXCEPT(type,...)
void setCommonTangentPoint(lsst::geom::Point2D const &commonTangentPoint)
Sets a shared tangent point for all ccdImages.
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.
MeasuredStarList const & getCatalogForFit() const
Gets the catalog to be used for fitting, which may have been cleaned-up.
Combinatorial searches for linear transformations to go from list1 to list2.
BaseStarList & Fitted2Base(FittedStarList &This)
std::shared_ptr< const BaseStar > s2
BaseStarList & Measured2Base(MeasuredStarList &This)
std::shared_ptr< RecordT > const get(size_type i) const
std::shared_ptr< const BaseStar > s1
std::string sourceFluxField
"name of flux field in source catalog" ;
lsst::sphgeom::Circle computeBoundingCircle() const
Return the bounding circle in on-sky (RA, Dec) coordinates containing all CcdImages.
#define LOGLS_FATAL(logger, message)
Handler of an actual image from a single CCD.
std::shared_ptr< FittedStar > getFittedStar() const
The objects which have been measured several times.
BaseStarList & Ref2Base(RefStarList &This)
T emplace_back(T... args)