def writeCatalog(self, allSource, wcsDic, calibDic, ffpDic): num = sum( sum(1 for src in ss if src.getExp() >= 0 and src.getChip() >= 0) for ss in allSource) import pyfits schema = pyfits.ColDefs([ pyfits.Column(name="id", format="K"), pyfits.Column(name="ra", format="D"), pyfits.Column(name="dec", format="D"), pyfits.Column(name="mag", format="E"), pyfits.Column(name="err", format="E"), pyfits.Column(name="corr", format="E"), ]) outHdu = pyfits.new_table(schema, nrows=num) outData = outHdu.data i = 0 for ss in allSource: for src in ss: iexp = src.getExp() ichip = src.getChip() if iexp < 0 or ichip < 0: continue outData.id[i] = src.getId() x, y = src.getX(), src.getY() wcs = wcsDic[iexp][ichip] ra, dec = wcs.pixelToSky(x, y).getPosition(afwGeom.degrees) outData.ra[i] = ra outData.dec[i] = dec fluxMag0 = calibDic[iexp][ichip].getFluxMag0()[0] flux = src.getFlux() if flux > 0 and fluxMag0 > 0: mcor = ffpDic[iexp][ichip].eval(x, y) jcor = -2.5 * math.log10( measMosaic.computeJacobian(wcs, afwGeom.Point2D(x, y))) outData.mag[i] = -2.5 * math.log10( flux / fluxMag0) + mcor + jcor outData.err[i] = 2.5 / math.log( 10) * src.getFluxErr() / flux outData.corr[i] = mcor + jcor i += 1 outHdu.writeto("catalog_check.fits", clobber=True)
def writeCatalog(self, allSource, wcsDic, calibDic, ffpDic): num = sum(sum(1 for src in ss if src.getExp() >=0 and src.getChip() >= 0) for ss in allSource) from astropy.io import fits schema = fits.ColDefs([fits.Column(name="id", format="K"), fits.Column(name="ra", format="D"), fits.Column(name="dec", format="D"), fits.Column(name="mag", format="E"), fits.Column(name="err", format="E"), fits.Column(name="corr", format="E"), ]) outHdu = fits.new_table(schema, nrows=num) outData = outHdu.data i = 0 for ss in allSource: for src in ss: iexp = src.getExp() ichip = src.getChip() if iexp < 0 or ichip < 0: continue outData.id[i] = src.getId() x, y = src.getX(), src.getY() wcs = wcsDic[iexp][ichip] ra, dec = wcs.pixelToSky(x, y).getPosition(afwGeom.degrees) outData.ra[i] = ra outData.dec[i] = dec fluxMag0 = calibDic[iexp][ichip].getInstFluxAtZeroMagnitude() flux = src.getFlux() if flux > 0 and fluxMag0 > 0: mcor = ffpDic[iexp][ichip].eval(x, y) jcor = -2.5*math.log10(measMosaic.computeJacobian(wcs, afwGeom.Point2D(x, y))) outData.mag[i] = -2.5*math.log10(flux/fluxMag0) + mcor + jcor outData.err[i] = 2.5/math.log(10) * src.getFluxErr() / flux outData.corr[i] = mcor + jcor i += 1 outHdu.writeto("catalog_check.fits", clobber=True)
def run(self, matchLists, filterName, wcsList, butler): if self.config.applyColorTerms: ct = self.config.colorterms.selectColorTerm(filterName) else: ct = None # Convert matchLists to meas_mosaic specific format mlVisit = dict() for ccdId in matchLists: if matchLists[ccdId] is None: continue visit, ccd = self.decodeCcdExposureId(ccdId) if visit not in mlVisit: mlVisit[visit] = list() matches = [m for m in matchLists[ccdId] if m[0] is not None] keys = self.getKeys(matches[0][1].schema) matches = self.selectMatches(matches, keys) matches = self.selectStars(matches) # Apply color term if ct is not None and len(matches) != 0: refSchema = matches[0][0].schema key_p = refSchema.find(ct.primary).key key_s = refSchema.find(ct.secondary).key key_f = refSchema.find("flux").key refFlux1 = numpy.array([m[0].get(key_p) for m in matches]) refFlux2 = numpy.array([m[0].get(key_s) for m in matches]) refMag1 = -2.5 * numpy.log10(refFlux1) refMag2 = -2.5 * numpy.log10(refFlux2) refMag = ct.transformMags(refMag1, refMag2) refFlux = numpy.power(10.0, -0.4 * refMag) matches = [ self.setCatFlux(m, f, key_f) for m, f in zip(matches, refFlux) if f == f ] for m in matches: if m[0] is not None and m[1] is not None: match = (measMosaic.Source(m[0], wcsList[ccdId]), measMosaic.Source(m[1])) match[1].setExp(visit) match[1].setChip(ccd) mlVisit[visit].append(match) matchList = [] for visit in mlVisit: matchList.append(mlVisit[visit]) rootMat = measMosaic.kdtreeMat(matchList) allMat = rootMat.mergeMat() # Read CCD information ccdSet = {} for ccdId in matchLists: if matchLists[ccdId] is None: continue visit, ccd = self.decodeCcdExposureId(ccdId) if ccd not in ccdSet: ccdDev = cameraGeomUtils.findCcd(butler.mapper.camera, cameraGeom.Id(int(ccd))) ccdSet[ccd] = ccdDev # meas_mosaic specific wcs information wcsDic = {} for ccdId in wcsList: visit, ccd = self.decodeCcdExposureId(ccdId) if visit not in wcsDic and wcsList[ccdId] is not None: wcs = wcsList[ccdId] ccdDev = ccdSet[ccd] offset = afwGeom.Extent2D(ccdDev.getCenter().getPixels( ccdDev.getPixelSize())) wcsDic[visit] = wcs.copyAtShiftedPixelOrigin(offset) # meas_mosaic specific object list matchVec = measMosaic.obsVecFromSourceGroup(allMat, wcsDic, ccdSet) sourceVec = [] # Apply Jocabian correction calculated from wcs for m in matchVec: wcs = wcsList[m.iexp * 200 + m.ichip] m.mag -= 2.5 * math.log10( measMosaic.computeJacobian(wcs, afwGeom.Point2D(m.x, m.y))) fluxFitOrder = self.config.fluxFitOrder absolute = True chebyshev = True commonFluxCorr = False solveCcdScale = True ffpSet = {} for visit in wcsDic: ffp = measMosaic.FluxFitParams(fluxFitOrder, absolute, chebyshev) u_max, v_max = self.getExtent(matchVec) ffp.u_max = (math.floor(u_max / 10.) + 1) * 10 ffp.v_max = (math.floor(v_max / 10.) + 1) * 10 ffpSet[visit] = ffp fexp = {} fchip = {} matchVec, sourceVec, wcsDic, ccdSet, fexp, fchip, ffpSet = measMosaic.fluxFit( absolute, commonFluxCorr, matchVec, len(matchVec), sourceVec, len(sourceVec), wcsDic, ccdSet, fexp, fchip, ffpSet, solveCcdScale) self.writeFcr(butler, list(matchLists.keys()), ccdSet, filterName, fexp, fchip, ffpSet) return (1.0 / fexp[list(fexp.keys())[0]])
def mosaic(self, dataRefList, tractInfo, ct=None, debug=False, diagDir=".", diagnostics=False, snapshots=False, numCoresForReadSource=1, readTimeout=9999, verbose=False): self.log.info(str(self.config)) self.outputDir = os.path.join(diagDir, "%04d" % tractInfo.getId()) if ((diagnostics or snapshots) and not os.path.isdir(self.outputDir)): os.makedirs(self.outputDir) if self.config.nBrightest != 0: self.log.fatal("Config paremeter nBrightest is deprecated.") self.log.fatal("Please use cellSize and nStarPerCell.") self.log.fatal("Exiting ...") return [] dataRefListOverlapWithTract, dataRefListToUse = self.checkOverlapWithTract( tractInfo, dataRefList) sourceSet, matchList, dataRefListUsed = self.readCatalog( dataRefListToUse, ct, numCoresForReadSource, readTimeout, verbose) dataRefListToOutput = list( set(dataRefListUsed) & set(dataRefListOverlapWithTract)) ccdSet = self.readCcd(dataRefListUsed) if debug: for ccd in ccdSet.values(): self.log.info( str(ccd.getId().getSerial()) + " " + str(ccd.getCenter().getPixels(ccd.getPixelSize())) + " " + str(ccd.getOrientation().getYaw())) wcsDic = self.readWcs(dataRefListUsed, ccdSet) self.removeNonExistCcd(dataRefListUsed, ccdSet) if debug: for iexp, wcs in wcsDic.items(): self.log.info( str(iexp) + " " + str(wcs.getPixelOrigin()) + " " + str(wcs.getSkyOrigin().getPosition(afwGeom.degrees))) self.log.info("frameIds : " + str(list(wcsDic.keys()))) self.log.info("ccdIds : " + str(list(ccdSet.keys()))) d_lim = afwGeom.Angle(self.config.radXMatch, afwGeom.arcseconds) if debug: self.log.info("d_lim : %f" % d_lim) allMat, allSource = self.mergeCatalog(sourceSet, matchList, ccdSet, d_lim) self.log.info("Flag suspect objects") measMosaic.flagSuspect(allMat, allSource, wcsDic) if self.config.clipSourcesOutsideTract: tractBBox = afwGeom.Box2D(tractInfo.getBBox()) tractWcs = tractInfo.getWcs() allSourceClipped = [ ss for ss in allSource if tractBBox.contains(tractWcs.skyToPixel(ss[0].getSky())) ] self.log.info("Num of allSources: %d" % (len(allSource))) self.log.info("Num of clipped allSources: %d" % (len(allSourceClipped))) allSource = allSourceClipped self.log.info("Make obsVec") nmatch = len(allMat) nsource = len(allSource) matchVec = measMosaic.obsVecFromSourceGroup(allMat, wcsDic, ccdSet) sourceVec = measMosaic.obsVecFromSourceGroup(allSource, wcsDic, ccdSet) self.log.info("Solve mosaic ...") order = self.config.fittingOrder internal = self.config.internalFitting solveCcd = self.config.solveCcd allowRotation = self.config.allowRotation fluxFitOrder = self.config.fluxFitOrder chebyshev = self.config.chebyshev absolute = self.config.fluxFitAbsolute solveCcdScale = self.config.fluxFitSolveCcd catRMS = self.config.catRMS if not internal: sourceVec = [] if debug: self.log.info("order : %d" % order) self.log.info("internal : %r" % internal) self.log.info("solveCcd : %r " % solveCcd) self.log.info("allowRotation : %r" % allowRotation) if self.config.doSolveWcs: if internal: coeffSet, matchVec, sourceVec, wcsDic, ccdSet = measMosaic.solveMosaic_CCD( order, nmatch, nsource, matchVec, sourceVec, wcsDic, ccdSet, solveCcd, allowRotation, verbose, catRMS, snapshots, self.outputDir) else: coeffSet, matchVec, wcsDic, ccdSet = measMosaic.solveMosaic_CCD_shot( order, nmatch, matchVec, wcsDic, ccdSet, solveCcd, allowRotation, verbose, catRMS, snapshots, self.outputDir) self.matchVec = matchVec self.sourceVec = sourceVec self.wcsDic = wcsDic self.ccdSet = ccdSet self.coeffSet = coeffSet self.writeNewWcs(dataRefListToOutput) if diagnostics: self.outputDiagWcs() for m in matchVec: coeff = coeffSet[m.iexp] scale = coeff.pixelScale() m.mag -= 2.5 * math.log10(coeff.detJ(m.u, m.v) / scale**2) if len(sourceVec) != 0: for s in sourceVec: coeff = coeffSet[s.iexp] scale = coeff.pixelScale() s.mag -= 2.5 * math.log10(coeff.detJ(s.u, s.v) / scale**2) else: wcsAll = dict() for dataRef in dataRefListUsed: frameId = "%07d-%03d" % (dataRef.dataId["visit"], dataRef.dataId["ccd"]) md = dataRef.get("calexp_md") wcsAll[frameId] = afwGeom.makeSkyWcs(md) del md for m in matchVec: wcs = wcsAll["%07d-%03d" % (m.iexp, m.ichip)] m.mag -= 2.5 * math.log10( measMosaic.computeJacobian(wcs, afwGeom.Point2D(m.x, m.y))) if len(sourceVec) != 0: for s in sourceVec: wcs = wcsAll["%07d-%03d" % (s.iexp, s.ichip)] s.mag -= 2.5 * math.log10( measMosaic.computeJacobian(wcs, afwGeom.Point2D(s.x, s.y))) del wcsAll if self.config.doSolveFlux: ffpSet = {} for visit in wcsDic: ffp = measMosaic.FluxFitParams(fluxFitOrder, absolute, chebyshev) u_max, v_max = mosaicUtils.getExtent(matchVec) ffp.u_max = (math.floor(u_max / 10.0) + 1) * 10 ffp.v_max = (math.floor(v_max / 10.0) + 1) * 10 ffpSet[visit] = ffp fexp = {} fchip = {} matchVec, sourceVec, wcsDic, ccdSet, fexp, fchip, ffpSet = measMosaic.fluxFit( absolute, self.config.commonFluxCorr, matchVec, len(matchVec), sourceVec, len(sourceVec), wcsDic, ccdSet, fexp, fchip, ffpSet, solveCcdScale) self.ffpSet = ffpSet self.fexp = fexp self.fchip = fchip self.writeFcr(dataRefListToOutput) if diagnostics: self.outputDiagFlux() if diagnostics and self.config.doSolveWcs and self.config.doSolveFlux: if len(sourceVec) != 0: mosaicUtils.writeCatalog( coeffSet, ffpSet, fexp, fchip, matchVec, sourceVec, os.path.join(self.outputDir, "catalog.fits")) return list(wcsDic.keys())
def makeDiffPosFlux(self, allMat, allSource, wcsDic, calibDic, ffpDic): dx_m = list() dy_m = list() dx_s = list() dy_s = list() m0_m = list() dm_m = list() m0_s = list() dm_s = list() for ss in allMat: ra_cat = ss[0].getRa().asDegrees() dec_cat = ss[0].getDec().asDegrees() mag_cat = -2.5*math.log10(ss[0].getFlux()) for j in range(1,len(ss)): if (ss[j].getFlux() > 0 and ss[j].getFlux() != float('inf')): iexp = ss[j].getExp() ichip = ss[j].getChip() x, y = ss[j].getX(), ss[j].getY() wcs = wcsDic[iexp][ichip] ra, dec = wcs.pixelToSky(x, y).getPosition(afwGeom.degrees) dx_m.append((ra - ra_cat) * 3600) dy_m.append((dec - dec_cat) * 3600) mag = 2.5*math.log10(calibDic[iexp][ichip].getInstFluxAtZeroMagnitude()/ss[j].getFlux()) mcor = ffpDic[iexp][ichip].eval(x,y) jcor = -2.5*math.log10(measMosaic.computeJacobian(wcs, afwGeom.Point2D(x, y))) m0_m.append(mag_cat) dm_m.append(mag+mcor+jcor-mag_cat) if len(ss) > 2: n = 0 ra_cat = 0.0 dec_cat = 0.0 S = 0.0 Sx = 0.0 ra_source = list() dec_source = list() mag_source = list() for j in range(1,len(ss)): if (ss[j].getFlux() > 0 and ss[j].getFlux() != float('inf')): iexp = ss[j].getExp() ichip = ss[j].getChip() x, y = ss[j].getX(), ss[j].getY() wcs = wcsDic[iexp][ichip] ra, dec = wcs.pixelToSky(x, y).getPosition(afwGeom.degrees) ra_source.append(ra) dec_source.append(dec) n += 1 ra_cat += ra dec_cat += dec mag = 2.5*math.log10(calibDic[iexp][ichip].getInstFluxAtZeroMagnitude()/ss[j].getFlux()) err = 2.5 / math.log(10) * ss[j].getFluxErr() / ss[j].getFlux() mcor = ffpDic[iexp][ichip].eval(x,y) jcor = -2.5*math.log10(measMosaic.computeJacobian(wcs, afwGeom.Point2D(x, y))) mag_source.append(mag+mcor+jcor) Sx += (mag+mcor+jcor) / (err*err) S += 1. / (err*err) if n != 0 and S != 0: ra_cat /= n dec_cat /= n mag_cat = Sx / S for ra, dec, mag in zip(ra_source, dec_source, mag_source): dx_s.append((ra - ra_cat) * 3600) dy_s.append((dec - dec_cat) * 3600) m0_s.append(mag_cat) dm_s.append(mag - mag_cat) dx_m = numpy.array(dx_m) dy_m = numpy.array(dy_m) m0_m = numpy.array(m0_m) dm_m = numpy.array(dm_m) for ss in allSource: n = 0 ra_cat = 0.0 dec_cat = 0.0 Sx = 0.0 S = 0.0 ra_source = list() dec_source = list() mag_source = list() for j in range(1,len(ss)): if (ss[j].getFlux() > 0 and ss[j].getFlux() != float('inf')): iexp = ss[j].getExp() ichip = ss[j].getChip() x, y = ss[j].getX(), ss[j].getY() wcs = wcsDic[iexp][ichip] ra, dec = wcs.pixelToSky(x, y).getPosition(afwGeom.degrees) ra_source.append(ra) dec_source.append(dec) n += 1 ra_cat += ra dec_cat += dec mag = 2.5*math.log10(calibDic[iexp][ichip].getInstFluxAtZeroMagnitude()/ss[j].getFlux()) err = 2.5 / math.log(10) * ss[j].getFluxErr() / ss[j].getFlux() mcor = ffpDic[iexp][ichip].eval(x,y) jcor = -2.5*math.log10(measMosaic.computeJacobian(wcs, afwGeom.Point2D(x, y))) mag_source.append(mag+mcor+jcor) Sx += (mag+mcor+jcor) / (err*err) S += 1. / (err*err) if n != 0: ra_cat /= n dec_cat /= n mag_cat = Sx / S for ra, dec, mag in zip(ra_source, dec_source, mag_source): dx_s.append((ra - ra_cat) * 3600) dy_s.append((dec - dec_cat) * 3600) m0_s.append(mag_cat) dm_s.append(mag - mag_cat) dx_s = numpy.array(dx_s) dy_s = numpy.array(dy_s) m0_s = numpy.array(m0_s) dm_s = numpy.array(dm_s) return dx_m, dy_m, dx_s, dy_s, m0_m, dm_m, m0_s, dm_s
def makeFluxStat(self, allMat, allSource, calibDic, ffpDic, wcsDic): x = list() y = list() ra = list() dec = list() id = list() for ss in allMat: Sxx = 0.0 Sx = 0.0 S = 0.0 Sr = 0.0 Sd = 0.0 if len(ss) > 2: for j in range(1,len(ss)): iexp = ss[j].getExp() ichip = ss[j].getChip() if ss[j].getFlux() > 0.0: mag = calibDic[iexp][ichip].instFluxToMagnitude(ss[j].getFlux()) err = 2.5 / math.log(10) * ss[j].getFluxErr() / ss[j].getFlux() xs, ys = ss[j].getX(), ss[j].getY() mcor = ffpDic[iexp][ichip].eval(xs, ys) wcs = wcsDic[iexp][ichip] jcor = -2.5*math.log10(measMosaic.computeJacobian(wcs, afwGeom.Point2D(xs, ys))) Sxx += (mag+mcor+jcor)*(mag+mcor+jcor) / (err*err) Sx += (mag+mcor+jcor) / (err*err) S += 1. / (err*err) Sr += ss[j].getRa().asDegrees() Sd += ss[j].getDec().asDegrees() avg = Sx / S sig = math.sqrt(Sxx/S - avg*avg) x.append(avg) y.append(sig) ra.append(Sr / (len(ss)-1)) dec.append(Sd / (len(ss)-1)) for ss in allSource: Sxx = 0.0 Sx = 0.0 S = 0.0 Sr = 0.0 Sd = 0.0 for j in range(1,len(ss)): iexp = ss[j].getExp() ichip = ss[j].getChip() #print iexp, ichip, calibDic[iexp][ichip].getInstFluxAtZeroMagnitude(), ss[j].getFlux() if calibDic[iexp][ichip].getInstFluxAtZeroMagnitude() > 0 and ss[j].getFlux() > 0.0: mag = calibDic[iexp][ichip].instFluxToMagnitude(ss[j].getFlux()) err = 2.5 / math.log(10) * ss[j].getFluxErr() / ss[j].getFlux() xs, ys = ss[j].getX(), ss[j].getY() mcor = ffpDic[iexp][ichip].eval(xs, ys) wcs = wcsDic[iexp][ichip] jcor = -2.5*math.log10(measMosaic.computeJacobian(wcs, afwGeom.Point2D(xs, ys))) Sxx += (mag+mcor+jcor)*(mag+mcor+jcor) / (err*err) Sx += (mag+mcor+jcor) / (err*err) S += 1. / (err*err) Sr += ss[j].getRa().asDegrees() Sd += ss[j].getDec().asDegrees() if S > 0: try: avg = Sx / S sig = math.sqrt(Sxx/S - avg*avg) x.append(avg) y.append(sig) ra.append(Sr / (len(ss)-1)) dec.append(Sd / (len(ss)-1)) except Exception as e: #print Sxx, S, avg, Sxx/S - avg*avg, len(ss)-1 pass if True: plt.clf() plt.plot(x, y, ',', markeredgewidth=0) plt.xlim(15, 25) plt.ylim(0.0, 0.20) plt.plot([15, 25], [0.01, 0.01], 'k--') plt.xlabel('mag (avg)') plt.ylabel('RMS') #plt.title('r-band') plt.savefig('fluxMean.png') else: for r, d, m, dm in zip(ra, dec, x, y): print('%9.5f %9.5f %7.4f %7.4f' % (r, d, m ,dm))
def run(self, dataRefList, tractInfo, ct=None, debug=False, diagDir=".", diagnostics=False, snapshots=False, numCoresForReadSource=1, readTimeout=9999, verbose=False): self.log.info(str(self.config)) self.outputDir = os.path.join(diagDir, "%04d" % tractInfo.getId()) if ((diagnostics or snapshots) and not os.path.isdir(self.outputDir)): os.makedirs(self.outputDir) if self.config.nBrightest != 0: self.log.fatal("Config paremeter nBrightest is deprecated.") self.log.fatal("Please use cellSize and nStarPerCell.") self.log.fatal("Exiting ...") return [] dataRefListOverlapWithTract, dataRefListToUse = self.checkOverlapWithTract(tractInfo, dataRefList) sourceSet, matchList, dataRefListUsed = self.readCatalog(dataRefListToUse, ct, numCoresForReadSource, readTimeout, verbose) if not matchList: raise RuntimeError("No reference source matches found") dataRefListToOutput = list(set(dataRefListUsed) & set(dataRefListOverlapWithTract)) ccdSet = self.readCcd(dataRefListUsed) if debug: for ccd in ccdSet.values(): self.log.info(str(ccd.getId().getSerial()) + " " + str(ccd.getCenter().getPixels(ccd.getPixelSize())) + " " + str(ccd.getOrientation().getYaw())) wcsDic = self.readWcs(dataRefListUsed, ccdSet) self.removeNonExistCcd(dataRefListUsed, ccdSet) if debug: for iexp, wcs in wcsDic.items(): self.log.info(str(iexp) + " " + str(wcs.getPixelOrigin()) + " " + str(wcs.getSkyOrigin().getPosition(afwGeom.degrees))) self.log.info("frameIds : " + str(list(wcsDic.keys()))) self.log.info("ccdIds : " + str(list(ccdSet.keys()))) d_lim = afwGeom.Angle(self.config.radXMatch, afwGeom.arcseconds) if debug: self.log.info("d_lim : %f" % d_lim) allMat, allSource =self.mergeCatalog(sourceSet, matchList, ccdSet, d_lim) self.log.info("Flag suspect objects") measMosaic.flagSuspect(allMat, allSource, wcsDic) if self.config.clipSourcesOutsideTract: tractBBox = afwGeom.Box2D(tractInfo.getBBox()) tractWcs = tractInfo.getWcs() allSourceClipped = [ss for ss in allSource if tractBBox.contains(tractWcs.skyToPixel(ss[0].getSky()))] self.log.info("Num of allSources: %d" % (len(allSource))) self.log.info("Num of clipped allSources: %d" % (len(allSourceClipped))) allSource = allSourceClipped self.log.info("Make obsVec") nmatch = len(allMat) nsource = len(allSource) matchVec = measMosaic.obsVecFromSourceGroup(allMat, wcsDic, ccdSet) sourceVec = measMosaic.obsVecFromSourceGroup(allSource, wcsDic, ccdSet) self.log.info("Solve mosaic ...") order = self.config.fittingOrder internal = self.config.internalFitting solveCcd = self.config.solveCcd allowRotation = self.config.allowRotation fluxFitOrder = self.config.fluxFitOrder chebyshev = self.config.chebyshev absolute = self.config.fluxFitAbsolute solveCcdScale = self.config.fluxFitSolveCcd catRMS = self.config.catRMS if not internal: sourceVec = [] if debug: self.log.info("order : %d" % order) self.log.info("internal : %r" % internal) self.log.info("solveCcd : %r " % solveCcd) self.log.info("allowRotation : %r" % allowRotation) if self.config.doSolveWcs: if internal: coeffSet, matchVec, sourceVec, wcsDic, ccdSet = measMosaic.solveMosaic_CCD(order, nmatch, nsource, matchVec, sourceVec, wcsDic, ccdSet, solveCcd, allowRotation, verbose, catRMS, snapshots, self.outputDir) else: coeffSet, matchVec, wcsDic, ccdSet = measMosaic.solveMosaic_CCD_shot(order, nmatch, matchVec, wcsDic, ccdSet, solveCcd, allowRotation, verbose, catRMS, snapshots, self.outputDir) self.matchVec = matchVec self.sourceVec = sourceVec self.wcsDic = wcsDic self.ccdSet = ccdSet self.coeffSet = coeffSet self.writeNewWcs(dataRefListToOutput) if diagnostics: self.outputDiagWcs() for m in matchVec: coeff = coeffSet[m.iexp] scale = coeff.pixelScale() m.mag -= 2.5*math.log10(coeff.detJ(m.u, m.v)/scale**2) if len(sourceVec) != 0: for s in sourceVec: coeff = coeffSet[s.iexp] scale = coeff.pixelScale() s.mag -= 2.5*math.log10(coeff.detJ(s.u, s.v)/scale**2) else: wcsAll = dict() for dataRef in dataRefListUsed: frameId = "%07d-%03d" % (dataRef.dataId["visit"], dataRef.dataId["ccd"]) md = dataRef.get("calexp_md") wcsAll[frameId] = afwGeom.makeSkyWcs(md) del md for m in matchVec: wcs = wcsAll["%07d-%03d" % (m.iexp, m.ichip)] m.mag -= 2.5*math.log10(measMosaic.computeJacobian(wcs, afwGeom.Point2D(m.x, m.y))) if len(sourceVec) != 0: for s in sourceVec: wcs = wcsAll["%07d-%03d" % (s.iexp, s.ichip)] s.mag -= 2.5*math.log10(measMosaic.computeJacobian(wcs, afwGeom.Point2D(s.x, s.y))) del wcsAll if self.config.doSolveFlux: ffpSet = {} for visit in wcsDic: ffp = measMosaic.FluxFitParams(fluxFitOrder, absolute, chebyshev) u_max, v_max = mosaicUtils.getExtent(matchVec) ffp.u_max = (math.floor(u_max/10.0) + 1)*10 ffp.v_max = (math.floor(v_max/10.0) + 1)*10 ffpSet[visit] = ffp fexp = {} fchip = {} matchVec, sourceVec, wcsDic, ccdSet, fexp, fchip, ffpSet = measMosaic.fluxFit(absolute, self.config.commonFluxCorr, matchVec, len(matchVec), sourceVec, len(sourceVec), wcsDic, ccdSet, fexp, fchip, ffpSet, solveCcdScale) self.ffpSet = ffpSet self.fexp = fexp self.fchip = fchip self.writeFcr(dataRefListToOutput) if diagnostics: self.outputDiagFlux() if diagnostics and self.config.doSolveWcs and self.config.doSolveFlux: if len(sourceVec) != 0: mosaicUtils.writeCatalog(coeffSet, ffpSet, fexp, fchip, matchVec, sourceVec, os.path.join(self.outputDir, "catalog.fits")) return list(wcsDic.keys())
def run(self, matchLists, filterName, wcsList, butler): if self.config.applyColorTerms: ct = self.config.colorterms.selectColorTerm(filterName) else: ct = None # Convert matchLists to meas_mosaic specific format mlVisit = dict() for ccdId in matchLists: if matchLists[ccdId] is None: continue visit, ccd = self.decodeCcdExposureId(ccdId) if visit not in mlVisit: mlVisit[visit] = list() matches = [m for m in matchLists[ccdId] if m[0] is not None] keys = self.getKeys(matches[0][1].schema) matches = self.selectMatches(matches, keys) matches = self.selectStars(matches) # Apply color term if ct is not None and len(matches) != 0: refSchema = matches[0][0].schema key_p = refSchema.find(ct.primary).key key_s = refSchema.find(ct.secondary).key key_f = refSchema.find("flux").key refFlux1 = numpy.array([m[0].get(key_p) for m in matches]) refFlux2 = numpy.array([m[0].get(key_s) for m in matches]) refMag1 = -2.5*numpy.log10(refFlux1) refMag2 = -2.5*numpy.log10(refFlux2) refMag = ct.transformMags(refMag1, refMag2) refFlux = numpy.power(10.0, -0.4*refMag) matches = [self.setCatFlux(m, f, key_f) for m, f in zip(matches, refFlux) if f == f] for m in matches: if m[0] is not None and m[1] is not None: match = (measMosaic.Source(m[0], wcsList[ccdId]), measMosaic.Source(m[1])) match[1].setExp(visit) match[1].setChip(ccd) mlVisit[visit].append(match) matchList = [] for visit in mlVisit: matchList.append(mlVisit[visit]) rootMat = measMosaic.kdtreeMat(matchList) allMat = rootMat.mergeMat() # Read CCD information ccdSet = {} for ccdId in matchLists: if matchLists[ccdId] is None: continue visit, ccd = self.decodeCcdExposureId(ccdId) if ccd not in ccdSet: ccdDev = cameraGeomUtils.findCcd(butler.mapper.camera, cameraGeom.Id(int(ccd))) ccdSet[ccd] = ccdDev # meas_mosaic specific wcs information wcsDic = {} for ccdId in wcsList: visit, ccd = self.decodeCcdExposureId(ccdId) if visit not in wcsDic and wcsList[ccdId] is not None: wcs = wcsList[ccdId] ccdDev = ccdSet[ccd] offset = afwGeom.Extent2D(ccdDev.getCenter().getPixels(ccdDev.getPixelSize())) wcsDic[visit] = wcs.copyAtShiftedPixelOrigin(offset) # meas_mosaic specific object list matchVec = measMosaic.obsVecFromSourceGroup(allMat, wcsDic, ccdSet) sourceVec = [] # Apply Jocabian correction calculated from wcs for m in matchVec: wcs = wcsList[m.iexp*200+m.ichip] m.mag -= 2.5*math.log10(measMosaic.computeJacobian(wcs, afwGeom.Point2D(m.x, m.y))) fluxFitOrder = self.config.fluxFitOrder absolute = True chebyshev = True commonFluxCorr = False solveCcdScale = True ffpSet = {} for visit in wcsDic: ffp = measMosaic.FluxFitParams(fluxFitOrder, absolute, chebyshev) u_max, v_max = self.getExtent(matchVec) ffp.u_max = (math.floor(u_max / 10.) + 1) * 10 ffp.v_max = (math.floor(v_max / 10.) + 1) * 10 ffpSet[visit] = ffp fexp = {} fchip = {} matchVec, sourceVec, wcsDic, ccdSet, fexp, fchip, ffpSet = measMosaic.fluxFit(absolute, commonFluxCorr, matchVec, len(matchVec), sourceVec, len(sourceVec), wcsDic, ccdSet, fexp, fchip, ffpSet, solveCcdScale) self.writeFcr(butler, list(matchLists.keys()), ccdSet, filterName, fexp, fchip, ffpSet) return (1.0/fexp[list(fexp.keys())[0]])