27 LOG_LOGGER _log =
LOG_GET(
"jointcal.Associations");
39 lsst::afw::geom::Box2I
const &bbox,
std::string const &filter,
43 auto ccdImage = std::make_shared<CcdImage>(catalog, wcs, visitInfo, bbox, filter, photoCalib, detector,
52 centers.
reserve(ccdImageList.size());
53 for (
auto const &
ccdImage : ccdImageList) {
56 auto commonTangentPoint = afw::geom::averageSpherePoint(centers);
57 LOGLS_DEBUG(_log,
"Using common tangent point: " << commonTangentPoint.getPosition(afw::geom::degrees));
58 setCommonTangentPoint(commonTangentPoint.getPosition(afw::geom::degrees));
62 _commonTangentPoint =
Point(commonTangentPoint.getX(), commonTangentPoint.getY());
63 for (
auto &
ccdImage : ccdImageList)
ccdImage->setCommonTangentPoint(_commonTangentPoint);
67 const bool enlargeFittedList) {
72 for (
auto &item : fittedStarList) {
73 item->clearBeforeAssoc();
76 if (!useFittedList) fittedStarList.clear();
78 for (
auto &
ccdImage : ccdImageList) {
79 const Gtransfo *toCommonTangentPlane =
ccdImage->getPix2CommonTangentPlane();
89 Frame ccdImageFrameCPT = toCommonTangentPlane->
apply(
ccdImage->getImageFrame(),
false);
90 ccdImageFrameCPT = ccdImageFrameCPT.
rescale(1.10);
95 for (
auto const &fittedStar : fittedStarList) {
96 if (ccdImageFrameCPT.
inFrame(*fittedStar)) {
103 toCommonTangentPlane, matchCutInArcSec / 3600.);
106 LOGLS_DEBUG(_log,
"Measured-to-Fitted matches before removing ambiguities " << starMatchList->size());
107 starMatchList->removeAmbiguities(*toCommonTangentPlane);
108 LOGLS_DEBUG(_log,
"Measured-to-Fitted matches after removing ambiguities " << starMatchList->size());
112 int matchedCount = 0;
113 for (
auto const &starMatch : *starMatchList) {
114 auto bs = starMatch.s1;
117 auto bs2 = starMatch.s2;
120 ms->setFittedStar(fs);
123 LOGLS_INFO(_log,
"Matched " << matchedCount <<
" objects in " <<
ccdImage->getName());
126 int unMatchedCount = 0;
127 for (
auto const &mstar : catalog) {
129 if (mstar->getFittedStar())
continue;
130 if (enlargeFittedList) {
131 auto fs = std::make_shared<FittedStar>(*mstar);
134 fittedStarList.push_back(fs);
135 mstar->setFittedStar(fs);
139 LOGLS_INFO(_log,
"Unmatched objects: " << unMatchedCount);
149 bool rejectBadFluxes) {
150 if (refCat.
size() == 0) {
152 " reference catalog is empty : stop here "));
163 << fluxField <<
"Sigma" 164 <<
") not found in reference catalog. Not using ref flux errors.");
167 _filterMap.reserve(refFluxMap.size());
169 for (
auto const &filter : refFluxMap) {
170 _filterMap[filter.first] = nFilters;
175 for (
size_t i = 0; i < refCat.
size(); i++) {
176 auto const &record = refCat.
get(i);
178 auto coord = record->get(coordKey);
180 double defaultFluxErr;
181 if (fluxErrKey.isValid()) {
188 for (
auto const &filter : _filterMap) {
189 fluxList[filter.second] = refFluxMap.
at(filter.first).at(i) /
JanskyToMaggy;
190 fluxErrList[filter.second] = refFluxErrMap.
at(filter.first).at(i) /
JanskyToMaggy;
194 auto star = std::make_shared<RefStar>(ra, dec, defaultFlux, defaultFluxErr, fluxList, fluxErrList);
200 star->vx =
std::pow(0.1 / 3600 /
cos(coord.getLatitude()), 2);
205 if (rejectBadFluxes &&
208 refStarList.push_back(star);
215 associateRefStars(matchCut.asArcseconds(), &raDec2CTP);
220 Frame tangentPlaneFrame;
222 for (
auto const &
ccdImage : ccdImageList) {
224 if (tangentPlaneFrame.
getArea() == 0)
225 tangentPlaneFrame = CTPFrame;
227 tangentPlaneFrame += CTPFrame;
233 Frame raDecFrame = CTP2RaDec.
apply(tangentPlaneFrame,
false);
235 lsst::afw::geom::Point<double>
min(raDecFrame.
xMin, raDecFrame.
yMin);
236 lsst::afw::geom::Point<double>
max(raDecFrame.
xMax, raDecFrame.
yMax);
237 lsst::afw::geom::Box2D box(min, max);
242 void Associations::associateRefStars(
double matchCutInArcSec,
const Gtransfo *
gtransfo) {
246 matchCutInArcSec / 3600.);
248 LOGLS_DEBUG(_log,
"Refcat matches before removing ambiguities " << starMatchList->size());
249 starMatchList->removeAmbiguities(*gtransfo);
250 LOGLS_DEBUG(_log,
"Refcat matches after removing ambiguities " << starMatchList->size());
253 for (
auto const &starMatch : *starMatchList) {
257 const BaseStar &bs2 = *starMatch.s2;
265 "Associated " << starMatchList->size() <<
" reference stars among " << refStarList.size());
269 selectFittedStars(minMeasurements);
270 normalizeFittedStars();
273 void Associations::selectFittedStars(
int minMeasurements) {
274 LOGLS_INFO(_log,
"Fitted stars before measurement # cut: " << fittedStarList.size());
277 for (
auto const &
ccdImage : ccdImageList) {
285 if (fittedStar ==
nullptr) {
292 if (!fittedStar->getRefStar() && fittedStar->getMeasurementCount() < minMeasurements) {
293 fittedStar->getMeasurementCount()--;
294 mi = catalog.
erase(mi);
303 if ((*fi)->getMeasurementCount() == 0) {
304 fi = fittedStarList.erase(fi);
310 LOGLS_INFO(_log,
"Fitted stars after measurement # cut: " << fittedStarList.size());
313 void Associations::normalizeFittedStars()
const {
315 for (
auto &fittedStar : fittedStarList) {
318 fittedStar->setFlux(0.0);
322 for (
auto const &
ccdImage : ccdImageList) {
323 const Gtransfo *toCommonTangentPlane =
ccdImage->getPix2CommonTangentPlane();
325 for (
auto &mi : catalog) {
326 auto fittedStar = mi->getFittedStar();
327 if (fittedStar ==
nullptr)
330 "All measuredStars must have a fittedStar: did you call selectFittedStars()?"));
331 auto point = toCommonTangentPlane->
apply(*mi);
332 fittedStar->x += point.x;
333 fittedStar->y += point.y;
334 fittedStar->getFlux() += mi->getFlux();
338 for (
auto &fi : fittedStarList) {
339 auto measurementCount = fi->getMeasurementCount();
340 fi->x /= measurementCount;
341 fi->y /= measurementCount;
342 fi->getFlux() /= measurementCount;
346 void Associations::assignMags() {
347 for (
auto const &
ccdImage : ccdImageList) {
349 for (
auto const &mstar : catalog) {
350 auto fstar = mstar->getFittedStar();
351 if (!fstar)
continue;
352 fstar->addMagMeasurement(mstar->getMag(), mstar->getMagWeight());
360 if (!fittedStarList.inTangentPlaneCoordinates) {
362 "DeprojectFittedStars: Fitted stars are already in sidereal coordinates, nothing done ");
367 fittedStarList.applyTransfo(ctp2Sky);
368 fittedStarList.inTangentPlaneCoordinates =
false;
373 return item->getCatalogForFit().size() > 0;
379 for (
auto const &fittedStar : fittedStarList) {
380 if ((fittedStar !=
nullptr) & (fittedStar->getRefStar() !=
nullptr)) count++;
386 void Associations::collectMCStars(
int realization) {
390 for (I = ccdImageList.begin(); I != ccdImageList.end(); I++) {
392 string dbimdir = ccdImage.Dir();
393 string mctruth = dbimdir +
"/mc/mctruth.list";
395 if (realization >= 0) {
397 sstrm << dbimdir <<
"/mc/mctruth_" << realization <<
".list";
398 mctruth = sstrm.
str();
405 DicStarList mctruthlist(mctruth);
409 for (smI = starMatchList->begin(); smI != starMatchList->end(); smI++) {
414 DicStar *dstar =
dynamic_cast<DicStar *
>(bs);
416 mcstar->GetMCInfo().iflux = dstar->getval(
"iflux");
417 mcstar->GetMCInfo().tflux = dstar->getval(
"sflux");
424 LOGLS_FATAL(_log,
"CollectMCStars Unable to match MCTruth w/ catalog!");
429 double matchCutArcSec) {
431 size_t pos_minus = color.
find(
'-');
432 bool compute_diff = (pos_minus != string::npos);
434 c1 = color.
substr(0, pos_minus);
435 if (compute_diff) c2 = color.
substr(pos_minus + 1, string::npos);
436 DicStarList cList(dicStarListName);
437 if (!cList.HasKey(c1))
438 throw(GastroException(
"Associations::SetFittedstarColors : " + dicStarListName +
439 " misses a key named \"" + c1 +
"\""));
440 if (compute_diff && !cList.HasKey(c2))
441 throw(GastroException(
"Associations::SetFittedstarColors : " + dicStarListName +
442 " misses a key named \"" + c2 +
"\""));
450 if (fittedStarList.inTangentPlaneCoordinates) id_or_proj = &id;
455 id_or_proj, matchCutArcSec / 3600);
457 LOGLS_INFO(_log,
"Matched " << starMatchList->size() <<
'/' << fittedStarList.size()
458 <<
" FittedStars to color catalog");
460 for (
auto i = starMatchList->begin(); i != starMatchList->end(); ++i) {
464 const TStar *ts =
dynamic_cast<const TStar *
>(s2);
465 const DicStar *ds =
dynamic_cast<const DicStar *
>(ts->get_original());
466 fs->
color = ds->getval(c1);
467 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...
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.
#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::createCcdImage.
Frame rescale(const double factor) const
rescale it. The center does not move.
#define LOGLS_INFO(logger, message)
double radToDeg(long double angleInRadians)
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.
void collectRefStars(afw::table::SimpleCatalog &refCat, afw::geom::Angle matchCut, std::string const &fluxField, RefFluxMapType const &refFluxMap=RefFluxMapType(), RefFluxMapType const &refFluxErrMap=RefFluxMapType(), bool rejectBadFluxes=false)
Collect stars from an external reference catalog and associate them with fittedStars.
rectangle with sides parallel to axes.
SchemaItem< T > find(std::string const &name) const
Class for a simple mapping implementing a generic Gtransfo.
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.
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.
bool inFrame(double x, double y) const
inside?
A do-nothing transformation. It anyway has dummy routines to mimick a Gtransfo.
#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.
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)
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" ;
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)