29 LOG_LOGGER _log =
LOG_GET(
"jointcal.Associations");
45 auto ccdImage = std::make_shared<CcdImage>(catalog, wcs, visitInfo, bbox, filter, photoCalib, detector,
53 _commonTangentPoint =
Point(commonTangentPoint.getX(), commonTangentPoint.getY());
54 for (
auto &
ccdImage : ccdImageList)
ccdImage->setCommonTangentPoint(_commonTangentPoint);
58 const bool enlargeFittedList) {
63 for (
auto &item : fittedStarList) {
64 item->clearBeforeAssoc();
67 if (!useFittedList) fittedStarList.clear();
69 for (
auto &
ccdImage : ccdImageList) {
70 const Gtransfo *toCommonTangentPlane =
ccdImage->getPix2CommonTangentPlane();
74 ccdImage->getCatalogForFit().clear();
82 ccdImageFrameCPT = ccdImageFrameCPT.
rescale(1.10);
87 for (
auto const &fittedStar : fittedStarList) {
88 if (ccdImageFrameCPT.inFrame(*fittedStar)) {
95 toCommonTangentPlane, matchCutInArcSec / 3600.);
98 LOGLS_DEBUG(_log,
"Measured-to-Fitted matches before removing ambiguities " << starMatchList->size());
99 starMatchList->removeAmbiguities(*toCommonTangentPlane);
100 LOGLS_DEBUG(_log,
"Measured-to-Fitted matches after removing ambiguities " << starMatchList->size());
104 int matchedCount = 0;
105 for (
auto const &starMatch : *starMatchList) {
106 auto bs = starMatch.s1;
109 auto bs2 = starMatch.s2;
112 ms->setFittedStar(fs);
115 LOGLS_INFO(_log,
"Matched " << matchedCount <<
" objects in " <<
ccdImage->getName());
118 int unMatchedCount = 0;
119 for (
auto const &mstar : catalog) {
121 if (mstar->getFittedStar())
continue;
122 if (enlargeFittedList) {
123 auto fs = std::make_shared<FittedStar>(*mstar);
126 fittedStarList.push_back(fs);
127 mstar->setFittedStar(fs);
131 LOGLS_INFO(_log,
"Unmatched objects: " << unMatchedCount);
141 bool rejectBadFluxes) {
142 if (refCat.
size() == 0) {
144 " reference catalog is empty : stop here "));
148 auto fluxKey = refCat.
getSchema().find<
double>(fluxField).key;
152 fluxErrKey = refCat.
getSchema().find<
double>(fluxField +
"Sigma").key;
155 << fluxField <<
"Sigma" 156 <<
") not found in reference catalog. Not using ref flux errors.");
159 _filterMap.reserve(refFluxMap.size());
161 for (
auto const &filter : refFluxMap) {
162 _filterMap[filter.first] = nFilters;
167 for (
size_t i = 0; i < refCat.
size(); i++) {
168 auto const &record = refCat.
get(i);
172 double defaultFluxErr;
173 if (fluxErrKey.isValid()) {
180 for (
auto const &filter : _filterMap) {
181 fluxList[filter.second] = refFluxMap.
at(filter.first).at(i) /
JanskyToMaggy;
182 fluxErrList[filter.second] = refFluxErrMap.
at(filter.first).at(i) /
JanskyToMaggy;
186 auto star = std::make_shared<RefStar>(ra, dec, defaultFlux, defaultFluxErr, fluxList, fluxErrList);
197 if (rejectBadFluxes &&
200 refStarList.push_back(star);
212 Frame tangentPlaneFrame;
214 for (
auto const &
ccdImage : ccdImageList) {
217 if (tangentPlaneFrame.
getArea() == 0)
218 tangentPlaneFrame = CTPFrame;
220 tangentPlaneFrame += CTPFrame;
235 void Associations::associateRefStars(
double matchCutInArcSec,
const Gtransfo *
gtransfo) {
239 matchCutInArcSec / 3600.);
241 LOGLS_DEBUG(_log,
"Refcat matches before removing ambiguities " << starMatchList->size());
242 starMatchList->removeAmbiguities(*gtransfo);
243 LOGLS_DEBUG(_log,
"Refcat matches after removing ambiguities " << starMatchList->size());
246 for (
auto const &starMatch : *starMatchList) {
250 const BaseStar &bs2 = *starMatch.s2;
258 "Associated " << starMatchList->size() <<
" reference stars among " << refStarList.size());
262 selectFittedStars(minMeasurements);
263 normalizeFittedStars();
266 void Associations::selectFittedStars(
int minMeasurements) {
267 LOGLS_INFO(_log,
"Fitted stars before measurement # cut: " << fittedStarList.size());
270 for (
auto const &
ccdImage : ccdImageList) {
278 if (fittedStar ==
nullptr) {
285 if (!fittedStar->getRefStar() && fittedStar->getMeasurementCount() < minMeasurements) {
286 fittedStar->getMeasurementCount()--;
287 mi = catalog.
erase(mi);
296 if ((*fi)->getMeasurementCount() == 0) {
297 fi = fittedStarList.erase(fi);
303 LOGLS_INFO(_log,
"Fitted stars after measurement # cut: " << fittedStarList.size());
306 void Associations::normalizeFittedStars()
const {
308 for (
auto &fittedStar : fittedStarList) {
311 fittedStar->setFlux(0.0);
315 for (
auto const &
ccdImage : ccdImageList) {
316 const Gtransfo *toCommonTangentPlane =
ccdImage->getPix2CommonTangentPlane();
318 for (
auto &mi : catalog) {
319 auto fittedStar = mi->getFittedStar();
320 if (fittedStar ==
nullptr)
323 "All measuredStars must have a fittedStar: did you call selectFittedStars()?"));
324 auto point = toCommonTangentPlane->
apply(*mi);
325 fittedStar->x += point.x;
326 fittedStar->y += point.y;
327 fittedStar->getFlux() += mi->getFlux();
331 for (
auto &fi : fittedStarList) {
332 auto measurementCount = fi->getMeasurementCount();
333 fi->x /= measurementCount;
334 fi->y /= measurementCount;
335 fi->getFlux() /= measurementCount;
339 void Associations::assignMags() {
340 for (
auto const &
ccdImage : ccdImageList) {
342 for (
auto const &mstar : catalog) {
343 auto fstar = mstar->getFittedStar();
344 if (!fstar)
continue;
345 fstar->addMagMeasurement(mstar->getMag(), mstar->getMagWeight());
353 if (!fittedStarList.inTangentPlaneCoordinates) {
355 "DeprojectFittedStars: Fitted stars are already in sidereal coordinates, nothing done ");
360 fittedStarList.applyTransfo(ctp2Sky);
361 fittedStarList.inTangentPlaneCoordinates =
false;
366 return item->getCatalogForFit().size() > 0;
372 for (
auto const &fittedStar : fittedStarList) {
373 if ((fittedStar !=
nullptr) & (fittedStar->getRefStar() !=
nullptr)) count++;
379 void Associations::collectMCStars(
int realization) {
383 for (I = ccdImageList.begin(); I != ccdImageList.end(); I++) {
385 string dbimdir = ccdImage.Dir();
386 string mctruth = dbimdir +
"/mc/mctruth.list";
388 if (realization >= 0) {
390 sstrm << dbimdir <<
"/mc/mctruth_" << realization <<
".list";
391 mctruth = sstrm.
str();
398 DicStarList mctruthlist(mctruth);
402 for (smI = starMatchList->begin(); smI != starMatchList->end(); smI++) {
407 DicStar *dstar =
dynamic_cast<DicStar *
>(bs);
409 mcstar->GetMCInfo().iflux = dstar->getval(
"iflux");
410 mcstar->GetMCInfo().tflux = dstar->getval(
"sflux");
417 LOGLS_FATAL(_log,
"CollectMCStars Unable to match MCTruth w/ catalog!");
422 double matchCutArcSec) {
424 size_t pos_minus = color.
find(
'-');
425 bool compute_diff = (pos_minus != string::npos);
427 c1 = color.
substr(0, pos_minus);
428 if (compute_diff) c2 = color.
substr(pos_minus + 1, string::npos);
429 DicStarList cList(dicStarListName);
430 if (!cList.HasKey(c1))
431 throw(GastroException(
"Associations::SetFittedstarColors : " + dicStarListName +
432 " misses a key named \"" + c1 +
"\""));
433 if (compute_diff && !cList.HasKey(c2))
434 throw(GastroException(
"Associations::SetFittedstarColors : " + dicStarListName +
435 " misses a key named \"" + c2 +
"\""));
443 if (fittedStarList.inTangentPlaneCoordinates) id_or_proj = &id;
448 id_or_proj, matchCutArcSec / 3600);
450 LOGLS_INFO(_log,
"Matched " << starMatchList->size() <<
'/' << fittedStarList.size()
451 <<
" FittedStars to color catalog");
453 for (
auto i = starMatchList->begin(); i != starMatchList->end(); ++i) {
457 const TStar *ts =
dynamic_cast<const TStar *
>(s2);
458 const DicStar *ds =
dynamic_cast<const DicStar *
>(ts->get_original());
459 fs->
color = ds->getval(c1);
460 if (compute_diff) fs->
color -= ds->getval(c2);
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.
lsst::afw::geom::Angle getLongitude() const
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
#define LOGLS_FATAL(logger, message)
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.
lsst::afw::geom::Angle getLatitude() const
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.
#define LOGLS_INFO(logger, message)
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.
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...
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) ...
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)
#define LOGLS_DEBUG(logger, message)
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" ;
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
#define LOGLS_WARN(logger, message)
BaseStarList & Ref2Base(RefStarList &This)
void addImage(lsst::afw::table::SortedCatalogT< lsst::afw::table::SourceRecord > &catalog, std::shared_ptr< lsst::afw::image::TanWcs > 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.