52 LOG_LOGGER _log =
LOG_GET(
"jointcal.Associations");
61 lsst::afw::geom::Box2I
const &bbox,
std::string const &filter,
65 auto ccdImage = std::make_shared<CcdImage>(catalog, wcs, visitInfo, bbox, filter, photoCalib, detector,
74 centers.
reserve(ccdImageList.size());
75 for (
auto const &
ccdImage : ccdImageList) {
78 auto commonTangentPoint = afw::geom::averageSpherePoint(centers);
79 LOGLS_DEBUG(_log,
"Using common tangent point: " << commonTangentPoint.getPosition(afw::geom::degrees));
80 setCommonTangentPoint(commonTangentPoint.getPosition(afw::geom::degrees));
84 _commonTangentPoint =
Point(commonTangentPoint.getX(), commonTangentPoint.getY());
85 for (
auto &
ccdImage : ccdImageList)
ccdImage->setCommonTangentPoint(_commonTangentPoint);
89 const bool enlargeFittedList) {
94 for (
auto &item : fittedStarList) {
95 item->clearBeforeAssoc();
98 if (!useFittedList) fittedStarList.clear();
100 for (
auto &
ccdImage : ccdImageList) {
111 Frame ccdImageFrameCPT = toCommonTangentPlane->apply(
ccdImage->getImageFrame(),
false);
112 ccdImageFrameCPT = ccdImageFrameCPT.
rescale(1.10);
117 for (
auto const &fittedStar : fittedStarList) {
118 if (ccdImageFrameCPT.
inFrame(*fittedStar)) {
125 toCommonTangentPlane.
get(), matchCutInArcSec / 3600.);
128 LOGLS_DEBUG(_log,
"Measured-to-Fitted matches before removing ambiguities " << starMatchList->size());
129 starMatchList->removeAmbiguities(*toCommonTangentPlane);
130 LOGLS_DEBUG(_log,
"Measured-to-Fitted matches after removing ambiguities " << starMatchList->size());
134 int matchedCount = 0;
135 for (
auto const &starMatch : *starMatchList) {
136 auto bs = starMatch.s1;
139 auto bs2 = starMatch.s2;
142 ms->setFittedStar(fs);
145 LOGLS_INFO(_log,
"Matched " << matchedCount <<
" objects in " <<
ccdImage->getName());
148 int unMatchedCount = 0;
149 for (
auto const &mstar : catalog) {
151 if (mstar->getFittedStar())
continue;
152 if (enlargeFittedList) {
153 auto fs = std::make_shared<FittedStar>(*mstar);
155 toCommonTangentPlane->transformPosAndErrors(*fs, *fs);
156 fittedStarList.push_back(fs);
157 mstar->setFittedStar(fs);
161 LOGLS_INFO(_log,
"Unmatched objects: " << unMatchedCount);
173 std::string const &fluxField,
bool rejectBadFluxes) {
174 if (refCat.
size() == 0) {
176 " reference catalog is empty : stop here "));
187 << fluxField <<
"Err" 188 <<
") not found in reference catalog. Not using ref flux errors.");
192 for (
size_t i = 0; i < refCat.
size(); i++) {
193 auto const &record = refCat.
get(i);
195 auto coord = record->get(coordKey);
196 double flux = record->get(fluxKey);
198 if (fluxErrKey.isValid()) {
199 fluxErr = record->get(fluxErrKey);
203 double ra = lsst::afw::geom::radToDeg(coord.getLongitude());
204 double dec = lsst::afw::geom::radToDeg(coord.getLatitude());
205 auto star = std::make_shared<RefStar>(ra, dec, flux, fluxErr);
211 star->vx =
std::pow(0.1 / 3600 /
cos(coord.getLatitude()), 2);
217 refStarList.push_back(star);
222 TanRaDecToPixel raDecToCommonTangentPlane(identity, _commonTangentPoint);
224 associateRefStars(matchCut.asArcseconds(), &raDecToCommonTangentPlane);
229 Frame tangentPlaneFrame;
231 for (
auto const &
ccdImage : ccdImageList) {
233 if (tangentPlaneFrame.
getArea() == 0)
234 tangentPlaneFrame = CTPFrame;
236 tangentPlaneFrame += CTPFrame;
241 TanPixelToRaDec commonTangentPlaneToRaDec(identity, _commonTangentPoint);
242 Frame raDecFrame = commonTangentPlaneToRaDec.
apply(tangentPlaneFrame,
false);
244 lsst::afw::geom::Point<double>
min(raDecFrame.
xMin, raDecFrame.
yMin);
245 lsst::afw::geom::Point<double>
max(raDecFrame.
xMax, raDecFrame.
yMax);
246 lsst::afw::geom::Box2D box(min, max);
255 matchCutInArcSec / 3600.);
257 LOGLS_DEBUG(_log,
"Refcat matches before removing ambiguities " << starMatchList->size());
258 starMatchList->removeAmbiguities(*transform);
259 LOGLS_DEBUG(_log,
"Refcat matches after removing ambiguities " << starMatchList->size());
262 for (
auto const &starMatch : *starMatchList) {
266 const BaseStar &bs2 = *starMatch.s2;
274 "Associated " << starMatchList->size() <<
" reference stars among " << refStarList.size());
278 selectFittedStars(minMeasurements);
279 normalizeFittedStars();
282 void Associations::selectFittedStars(
int minMeasurements) {
283 LOGLS_INFO(_log,
"Fitted stars before measurement # cut: " << fittedStarList.size());
285 int totalMeasured = 0, validMeasured = 0;
288 for (
auto const &
ccdImage : ccdImageList) {
297 if (fittedStar ==
nullptr) {
304 if (!fittedStar->getRefStar() && fittedStar->getMeasurementCount() < minMeasurements) {
305 fittedStar->getMeasurementCount()--;
306 mi = catalog.
erase(mi);
316 if ((*fi)->getMeasurementCount() == 0) {
317 fi = fittedStarList.erase(fi);
323 LOGLS_INFO(_log,
"Fitted stars after measurement # cut: " << fittedStarList.size());
324 LOGLS_INFO(_log,
"Total, valid number of Measured stars: " << totalMeasured <<
", " << validMeasured);
327 void Associations::normalizeFittedStars()
const {
329 for (
auto &fittedStar : fittedStarList) {
332 fittedStar->setFlux(0.0);
333 fittedStar->getMag() = 0.0;
337 for (
auto const &
ccdImage : ccdImageList) {
340 for (
auto &mi : catalog) {
341 auto fittedStar = mi->getFittedStar();
342 if (fittedStar ==
nullptr)
345 "All measuredStars must have a fittedStar: did you call selectFittedStars()?"));
346 auto point = toCommonTangentPlane->apply(*mi);
347 fittedStar->x += point.x;
348 fittedStar->y += point.y;
349 fittedStar->getFlux() += mi->getFlux();
353 for (
auto &fi : fittedStarList) {
354 auto measurementCount = fi->getMeasurementCount();
355 fi->x /= measurementCount;
356 fi->y /= measurementCount;
357 fi->getFlux() /= measurementCount;
358 fi->getMag() = utils::nanojanskyToABMagnitude(fi->getFlux());
362 void Associations::assignMags() {
363 for (
auto const &
ccdImage : ccdImageList) {
365 for (
auto const &mstar : catalog) {
366 auto fstar = mstar->getFittedStar();
367 if (!fstar)
continue;
368 fstar->addMagMeasurement(mstar->getMag(), mstar->getMagWeight());
376 if (!fittedStarList.inTangentPlaneCoordinates) {
378 "DeprojectFittedStars: Fitted stars are already in sidereal coordinates, nothing done ");
383 fittedStarList.applyTransform(ctp2Sky);
384 fittedStarList.inTangentPlaneCoordinates =
false;
389 return item->getCatalogForFit().size() > 0;
395 for (
auto const &fittedStar : fittedStarList) {
396 if ((fittedStar !=
nullptr) & (fittedStar->getRefStar() !=
nullptr)) count++;
402 void Associations::collectMCStars(
int realization) {
406 for (I = ccdImageList.begin(); I != ccdImageList.end(); I++) {
408 string dbimdir = ccdImage.Dir();
409 string mctruth = dbimdir +
"/mc/mctruth.list";
411 if (realization >= 0) {
413 sstrm << dbimdir <<
"/mc/mctruth_" << realization <<
".list";
414 mctruth = sstrm.
str();
421 DicStarList mctruthlist(mctruth);
425 for (smI = starMatchList->begin(); smI != starMatchList->end(); smI++) {
430 DicStar *dstar =
dynamic_cast<DicStar *
>(bs);
432 mcstar->GetMCInfo().iflux = dstar->getval(
"iflux");
433 mcstar->GetMCInfo().tflux = dstar->getval(
"sflux");
440 LOGLS_FATAL(_log,
"CollectMCStars Unable to match MCTruth w/ catalog!");
445 double matchCutArcSec) {
447 size_t pos_minus = color.
find(
'-');
448 bool compute_diff = (pos_minus != string::npos);
450 c1 = color.
substr(0, pos_minus);
451 if (compute_diff) c2 = color.
substr(pos_minus + 1, string::npos);
452 DicStarList cList(dicStarListName);
453 if (!cList.HasKey(c1))
454 throw(GastroException(
"Associations::SetFittedstarColors : " + dicStarListName +
455 " misses a key named \"" + c1 +
"\""));
456 if (compute_diff && !cList.HasKey(c2))
457 throw(GastroException(
"Associations::SetFittedstarColors : " + dicStarListName +
458 " misses a key named \"" + c2 +
"\""));
466 if (fittedStarList.inTangentPlaneCoordinates) id_or_proj = &id;
471 id_or_proj, matchCutArcSec / 3600);
473 LOGLS_INFO(_log,
"Matched " << starMatchList->size() <<
'/' << fittedStarList.size()
474 <<
" FittedStars to color catalog");
476 for (
auto i = starMatchList->begin(); i != starMatchList->end(); ++i) {
480 const TStar *ts =
dynamic_cast<const TStar *
>(s2);
481 const DicStar *ds =
dynamic_cast<const DicStar *
>(ts->get_original());
482 fs->
color = ds->getval(c1);
483 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.
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.
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.
void collectRefStars(afw::table::SimpleCatalog &refCat, afw::geom::Angle matchCut, std::string const &fluxField, bool rejectBadFluxes=false)
Collect stars from an external reference catalog and associate them with fittedStars.
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...
#define LOGLS_INFO(logger, message)
void setCommonTangentPoint(lsst::afw::geom::Point2D const &commonTangentPoint)
Sets a shared tangent point for all ccdImages.
bool inFrame(double x, double y) const
inside?
#define LSST_EXCEPT(type,...)
void createCcdImage(afw::table::SourceCatalog &catalog, std::shared_ptr< lsst::afw::geom::SkyWcs > wcs, std::shared_ptr< lsst::afw::image::VisitInfo > visitInfo, lsst::afw::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.
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
const lsst::afw::geom::Box2D getRaDecBBox()
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" ;
#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)