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);
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
#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.
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) ...
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)
#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)