28 LOG_LOGGER _log =
LOG_GET(
"jointcal.Associations");
44 auto ccdImage = std::make_shared<CcdImage>(catalog, wcs, visitInfo, bbox, filter, photoCalib, detector,
52 _commonTangentPoint =
Point(commonTangentPoint.getX(), commonTangentPoint.getY());
53 for (
auto &
ccdImage : ccdImageList)
ccdImage->setCommonTangentPoint(_commonTangentPoint);
57 const bool enlargeFittedList) {
62 for (
auto &item : fittedStarList) {
63 item->clearBeforeAssoc();
66 if (!useFittedList) fittedStarList.clear();
68 for (
auto &
ccdImage : ccdImageList) {
69 const Gtransfo *toCommonTangentPlane =
ccdImage->getPix2CommonTangentPlane();
73 ccdImage->getCatalogForFit().clear();
81 ccdImageFrameCPT = ccdImageFrameCPT.
rescale(1.10);
86 for (
auto const &fittedStar : fittedStarList) {
87 if (ccdImageFrameCPT.inFrame(*fittedStar)) {
94 toCommonTangentPlane, matchCutInArcSec / 3600.);
97 LOGLS_DEBUG(_log,
"Measured-to-Fitted matches before removing ambiguities " << starMatchList->size());
98 starMatchList->removeAmbiguities(*toCommonTangentPlane);
99 LOGLS_DEBUG(_log,
"Measured-to-Fitted matches after removing ambiguities " << starMatchList->size());
103 int matchedCount = 0;
104 for (
auto const &starMatch : *starMatchList) {
105 auto bs = starMatch.s1;
108 auto bs2 = starMatch.s2;
111 ms->setFittedStar(fs);
114 LOGLS_INFO(_log,
"Matched " << matchedCount <<
" objects in " <<
ccdImage->getName());
117 int unMatchedCount = 0;
118 for (
auto const &mstar : catalog) {
120 if (mstar->getFittedStar())
continue;
121 if (enlargeFittedList) {
122 auto fs = std::make_shared<FittedStar>(*mstar);
125 fittedStarList.push_back(fs);
126 mstar->setFittedStar(fs);
130 LOGLS_INFO(_log,
"Unmatched objects: " << unMatchedCount);
140 bool rejectBadFluxes) {
141 if (refCat.
size() == 0) {
143 " reference catalog is empty : stop here "));
147 auto fluxKey = refCat.
getSchema().find<
double>(fluxField).
key;
151 fluxErrKey = refCat.
getSchema().find<
double>(fluxField +
"Sigma").
key;
154 << fluxField <<
"Sigma" 155 <<
") not found in reference catalog. Not using ref flux errors.");
158 _filterMap.reserve(refFluxMap.size());
160 for (
auto const &filter : refFluxMap) {
161 _filterMap[filter.first] = nFilters;
166 for (
size_t i = 0; i < refCat.
size(); i++) {
167 auto const &record = refCat.
get(i);
169 auto coord = record->get(coordKey);
171 double defaultFluxErr;
172 if (fluxErrKey.isValid()) {
179 for (
auto const &filter : _filterMap) {
180 fluxList[filter.second] = refFluxMap.
at(filter.first).at(i) /
JanskyToMaggy;
181 fluxErrList[filter.second] = refFluxErrMap.
at(filter.first).at(i) /
JanskyToMaggy;
185 auto star = std::make_shared<RefStar>(ra, dec, defaultFlux, defaultFluxErr, fluxList, fluxErrList);
191 star->vx =
std::pow(0.1 / 3600 /
cos(coord.getLatitude()), 2);
196 if (rejectBadFluxes &&
199 refStarList.push_back(star);
211 Frame tangentPlaneFrame;
213 for (
auto const &
ccdImage : ccdImageList) {
216 if (tangentPlaneFrame.
getArea() == 0)
217 tangentPlaneFrame = CTPFrame;
219 tangentPlaneFrame += CTPFrame;
234 void Associations::associateRefStars(
double matchCutInArcSec,
const Gtransfo *
gtransfo) {
238 matchCutInArcSec / 3600.);
240 LOGLS_DEBUG(_log,
"Refcat matches before removing ambiguities " << starMatchList->size());
241 starMatchList->removeAmbiguities(*gtransfo);
242 LOGLS_DEBUG(_log,
"Refcat matches after removing ambiguities " << starMatchList->size());
245 for (
auto const &starMatch : *starMatchList) {
249 const BaseStar &bs2 = *starMatch.s2;
257 "Associated " << starMatchList->size() <<
" reference stars among " << refStarList.size());
261 selectFittedStars(minMeasurements);
262 normalizeFittedStars();
265 void Associations::selectFittedStars(
int minMeasurements) {
266 LOGLS_INFO(_log,
"Fitted stars before measurement # cut: " << fittedStarList.size());
269 for (
auto const &
ccdImage : ccdImageList) {
277 if (fittedStar ==
nullptr) {
284 if (!fittedStar->getRefStar() && fittedStar->getMeasurementCount() < minMeasurements) {
285 fittedStar->getMeasurementCount()--;
286 mi = catalog.
erase(mi);
295 if ((*fi)->getMeasurementCount() == 0) {
296 fi = fittedStarList.erase(fi);
302 LOGLS_INFO(_log,
"Fitted stars after measurement # cut: " << fittedStarList.size());
305 void Associations::normalizeFittedStars()
const {
307 for (
auto &fittedStar : fittedStarList) {
310 fittedStar->setFlux(0.0);
314 for (
auto const &
ccdImage : ccdImageList) {
315 const Gtransfo *toCommonTangentPlane =
ccdImage->getPix2CommonTangentPlane();
317 for (
auto &mi : catalog) {
318 auto fittedStar = mi->getFittedStar();
319 if (fittedStar ==
nullptr)
322 "All measuredStars must have a fittedStar: did you call selectFittedStars()?"));
323 auto point = toCommonTangentPlane->
apply(*mi);
324 fittedStar->x += point.x;
325 fittedStar->y += point.y;
326 fittedStar->getFlux() += mi->getFlux();
330 for (
auto &fi : fittedStarList) {
331 auto measurementCount = fi->getMeasurementCount();
332 fi->x /= measurementCount;
333 fi->y /= measurementCount;
334 fi->getFlux() /= measurementCount;
338 void Associations::assignMags() {
339 for (
auto const &
ccdImage : ccdImageList) {
341 for (
auto const &mstar : catalog) {
342 auto fstar = mstar->getFittedStar();
343 if (!fstar)
continue;
344 fstar->addMagMeasurement(mstar->getMag(), mstar->getMagWeight());
352 if (!fittedStarList.inTangentPlaneCoordinates) {
354 "DeprojectFittedStars: Fitted stars are already in sidereal coordinates, nothing done ");
359 fittedStarList.applyTransfo(ctp2Sky);
360 fittedStarList.inTangentPlaneCoordinates =
false;
365 return item->getCatalogForFit().size() > 0;
371 for (
auto const &fittedStar : fittedStarList) {
372 if ((fittedStar !=
nullptr) & (fittedStar->getRefStar() !=
nullptr)) count++;
378 void Associations::collectMCStars(
int realization) {
382 for (I = ccdImageList.begin(); I != ccdImageList.end(); I++) {
384 string dbimdir = ccdImage.Dir();
385 string mctruth = dbimdir +
"/mc/mctruth.list";
387 if (realization >= 0) {
389 sstrm << dbimdir <<
"/mc/mctruth_" << realization <<
".list";
390 mctruth = sstrm.
str();
397 DicStarList mctruthlist(mctruth);
401 for (smI = starMatchList->begin(); smI != starMatchList->end(); smI++) {
406 DicStar *dstar =
dynamic_cast<DicStar *
>(bs);
408 mcstar->GetMCInfo().iflux = dstar->getval(
"iflux");
409 mcstar->GetMCInfo().tflux = dstar->getval(
"sflux");
416 LOGLS_FATAL(_log,
"CollectMCStars Unable to match MCTruth w/ catalog!");
421 double matchCutArcSec) {
423 size_t pos_minus = color.
find(
'-');
424 bool compute_diff = (pos_minus != string::npos);
426 c1 = color.
substr(0, pos_minus);
427 if (compute_diff) c2 = color.
substr(pos_minus + 1, string::npos);
428 DicStarList cList(dicStarListName);
429 if (!cList.HasKey(c1))
430 throw(GastroException(
"Associations::SetFittedstarColors : " + dicStarListName +
431 " misses a key named \"" + c1 +
"\""));
432 if (compute_diff && !cList.HasKey(c2))
433 throw(GastroException(
"Associations::SetFittedstarColors : " + dicStarListName +
434 " misses a key named \"" + c2 +
"\""));
442 if (fittedStarList.inTangentPlaneCoordinates) id_or_proj = &id;
447 id_or_proj, matchCutArcSec / 3600);
449 LOGLS_INFO(_log,
"Matched " << starMatchList->size() <<
'/' << fittedStarList.size()
450 <<
" FittedStars to color catalog");
452 for (
auto i = starMatchList->begin(); i != starMatchList->end(); ++i) {
456 const TStar *ts =
dynamic_cast<const TStar *
>(s2);
457 const DicStar *ds =
dynamic_cast<const DicStar *
>(ts->get_original());
458 fs->
color = ds->getval(c1);
459 if (compute_diff) fs->
color -= ds->getval(c2);
#define LOGLS_WARN(logger, message)
Objects used as position anchors, typically USNO stars.
implements the linear transformations (6 real coefficients).
int nCcdImagesValidForFit() const
return the number of CcdImages with non-empty catalogs to-be-fit.
MeasuredStarList::iterator MeasuredStarIterator
A hanger for star associations.
the transformation that handles pix to sideral transfos (Gnomonic, possibly with polynomial distortio...
double xMin
coordinate of boundary.
constexpr double asArcseconds() const noexcept
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::AddImage.
Frame rescale(const double factor) const
rescale it. The center does not move.
void collectRefStars(lsst::afw::table::SortedCatalogT< lsst::afw::table::SimpleRecord > &refCat, afw::geom::Angle matchCut, std::string const &fluxField, std::map< std::string, std::vector< double >> const &refFluxMap, std::map< std::string, std::vector< double >> const &refFluxErrMap, bool rejectBadFluxes=false)
Collect stars from an external reference catalog and associate them with fittedStars.
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)
Class for a simple mapping implementing a generic Gtransfo.
void setRefStar(const RefStar *_refStar)
Set the astrometric reference star associated with this star.
FittedStarList::iterator FittedStarIterator
A list of FittedStar s. Such a list is typically constructed by Associations.
std::unique_ptr< StarMatchList > listMatchCollect(const BaseStarList &list1, const BaseStarList &list2, const Gtransfo *guess, const double maxDist)
assembles star matches.
virtual void transformPosAndErrors(const FatPoint &in, FatPoint &out) const
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.
A do-nothing transformation. It anyway has dummy routines to mimick a Gtransfo.
#define LSST_EXCEPT(type,...)
This one is the Tangent Plane (called gnomonic) projection (from celestial sphere to tangent plane) ...
void addImage(lsst::afw::table::SortedCatalogT< lsst::afw::table::SourceRecord > &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)
a virtual (interface) class for geometric transformations.
std::shared_ptr< const BaseStar > s2
const lsst::afw::geom::Box2D getRaDecBBox()
BaseStarList & Measured2Base(MeasuredStarList &This)
constexpr double radToDeg(double x) noexcept
std::shared_ptr< RecordT > const get(size_type i) const
std::shared_ptr< const BaseStar > s1
Frame applyTransfo(const Frame &inputframe, const Gtransfo >ransfo, const WhichTransformed which)
Transform a Frame through a Transfo.
std::string sourceFluxField
"name of flux field in source catalog" ;
#define LOGLS_FATAL(logger, message)
Handler of an actual image from a single CCD.
const double JanskyToMaggy
std::shared_ptr< FittedStar > getFittedStar() const
The objects which have been measured several times.
virtual void apply(const double xIn, const double yIn, double &xOut, double &yOut) const =0
BaseStarList & Ref2Base(RefStarList &This)