def makeLinearizerDecam(fromFile, force=False, verbose=False): """Convert the specified DECam linearity FITS table to standard LSST format Details: - Input format is one table per CCD, HDU is amplifier number, the table has 3 columns: ADU, ADU_LINEAR_A, ADU_LINEAR_B. The values of ADU contiguous (0, 1, 2...) but check and error out if not. The values of the latter two are replacements (0+delta0, 1+delta1, 2+delta2...) and this is converted to offsets for the LSST linearization tables (delta0, delta1, delta2...) - Output is a set of LinearizeLookupTable instances, one per CCD, saved as dataset type "linearizer" - The row indices for the linearization lookup table are (row index=amp name): 0=A, 1=B @param[in] fromFile path to DECam linearity table (a FITS file with one HDU per amplifier) """ print("Making DECam linearizers from %r" % (fromFile, )) butler = Butler(mapper=DecamMapper) linearizerDir = DecamMapper.getLinearizerDir() if os.path.exists(linearizerDir): if not force: print("Output directory %r exists; use --force to replace" % (linearizerDir, )) sys.exit(1) print("Replacing data in linearizer directory %r" % (linearizerDir, )) else: print("Creating linearizer directory %r" % (linearizerDir, )) os.makedirs(linearizerDir) camera = DecamMapper().camera fromHDUs = fits.open(fromFile)[1:] # HDU 0 has no data assert len(fromHDUs) == len(camera) for ccdind, (detector, hdu) in enumerate(zip(camera, fromHDUs)): ccdnum = ccdind + 1 if verbose: print("ccdnum=%s; detector=%s" % (ccdnum, detector.getName())) fromData = hdu.data assert len(fromData.dtype) == 3 lsstTable = np.zeros((2, len(fromData)), dtype=np.float32) uncorr = fromData["ADU"] if not np.allclose(uncorr, np.arange(len(fromData))): raise RuntimeError( "ADU data not a range of integers starting at 0") for i, ampName in enumerate("AB"): # convert DECam replacement table to LSST offset table if verbose: print("DECam table for %s=%s..." % ( ampName, fromData["ADU_LINEAR_" + ampName][0:5], )) lsstTable[i, :] = fromData["ADU_LINEAR_" + ampName] - uncorr if verbose: print("LSST table for %s=%s..." % ( ampName, lsstTable[i, 0:5], )) linearizer = LinearizeLookupTable(table=lsstTable, detector=detector) butler.put(linearizer, "linearizer", dataId=dict(ccdnum=ccdnum)) print("Wrote %s linearizers" % (ccdind + 1, ))
def getSourcesAndCoeffsFile(self, filename='DECam_xtalk_20130606.txt'): """File containing DECam crosstalk coefficients. This text file is provided by NOAO in a particular format with information about the DECam crosstalk coefficients. It is available at http://www.ctio.noao.edu/noao/content/DECam-Calibration-Files Parameters ---------- filename : `str`, optional File containing the decam crosstalk coefficients, from NOAO. Returns ------- result : `str` Full path to filename. """ mapper = DecamMapper() packageName = mapper.getPackageName() packageDir = getPackageDir(packageName) return os.path.join(packageDir, 'decam', filename)
def makeLinearizerDecam(fromFile, force=False, verbose=False): """Convert the specified DECam linearity FITS table to standard LSST format Details: - Input format is one table per CCD, HDU is amplifier number, the table has 3 columns: ADU, ADU_LINEAR_A, ADU_LINEAR_B. The values of ADU contiguous (0, 1, 2...) but check and error out if not. The values of the latter two are replacements (0+delta0, 1+delta1, 2+delta2...) and this is converted to offsets for the LSST linearization tables (delta0, delta1, delta2...) - Output is a set of LinearizeLookupTable instances, one per CCD, saved as dataset type "linearizer" - The row indices for the linearization lookup table are (row index=amp name): 0=A, 1=B @param[in] fromFile path to DECam linearity table (a FITS file with one HDU per amplifier) """ print("Making DECam linearizers from %r" % (fromFile,)) butler = Butler(mapper=DecamMapper) linearizerDir = DecamMapper.getLinearizerDir() if os.path.exists(linearizerDir): if not force: print("Output directory %r exists; use --force to replace" % (linearizerDir,)) sys.exit(1) print("Replacing data in linearizer directory %r" % (linearizerDir,)) else: print("Creating linearizer directory %r" % (linearizerDir,)) os.makedirs(linearizerDir) camera = DecamMapper().camera fromHDUs = fits.open(fromFile)[1:] # HDU 0 has no data assert len(fromHDUs) == len(camera) for ccdind, (detector, hdu) in enumerate(izip(camera, fromHDUs)): ccdnum = ccdind + 1 if verbose: print("ccdnum=%s; detector=%s" % (ccdnum, detector.getName())) fromData = hdu.data assert len(fromData.dtype) == 3 lsstTable = np.zeros((2, len(fromData)), dtype=np.float32) uncorr = fromData["ADU"] if not np.allclose(uncorr, np.arange(len(fromData))): raise RuntimeError("ADU data not a range of integers starting at 0") for i, ampName in enumerate("AB"): # convert DECam replacement table to LSST offset table if verbose: print("DECam table for %s=%s..." % (ampName, fromData["ADU_LINEAR_" + ampName][0:5],)) lsstTable[i,:] = fromData["ADU_LINEAR_" + ampName] - uncorr if verbose: print("LSST table for %s=%s..." % (ampName, lsstTable[i,0:5],)) linearizer = LinearizeLookupTable(table=lsstTable, detector=detector) butler.put(linearizer, "linearizer", dataId=dict(ccdnum=ccdnum)) print("Wrote %s linearizers" % (ccdind+1,))
def makeDetectorCrosstalk(dataDict, force=False): """Generate and write CrosstalkCalib from dictionary. Parameters ---------- dataDict : `dict` Dictionary from ``readFile`` containing crosstalk definition. """ dataDict['coeffs'] = dataDict['coeffs'].transpose() decamCT = ipIsr.crosstalk.CrosstalkCalib.fromDict(dataDict) # Supply a date prior to all data, to ensure universal use. decamCT.updateMetadata(setDate=False, CALIBDATE='1970-01-01T00:00:00') detName = dataDict['DETECTOR_NAME'] outDir = os.path.join(DecamMapper.getCrosstalkDir(), detName.lower()) if os.path.exists(outDir): if not force: print("Output directory %r exists; use --force to replace" % (outDir, )) sys.exit(1) else: os.makedirs(outDir) decamCT.writeText(f"{outDir}/1970-01-01T00:00:00.yaml")
camConfig.transformDict = tmc def makeDir(dirPath, doClobber=False): """Make a directory; if it exists then clobber or fail, depending on doClobber @param[in] dirPath: path of directory to create @param[in] doClobber: what to do if dirPath already exists: if True and dirPath is a dir, then delete it and recreate it, else raise an exception @throw RuntimeError if dirPath exists and doClobber False """ if os.path.exists(dirPath): if doClobber and os.path.isdir(dirPath): print "Clobbering directory %r" % (dirPath,) shutil.rmtree(dirPath) else: raise RuntimeError("Directory %r exists" % (dirPath,)) print "Creating directory %r" % (dirPath,) os.makedirs(dirPath) # write data products outDir = args.OutputDir makeDir(dirPath=outDir, doClobber=args.clobber) camConfigPath = os.path.join(outDir, "camera.py") camConfig.save(camConfigPath) for detectorName, ampTable in ampTableDict.iteritems(): shortDetectorName = DecamMapper.getShortCcdName(detectorName) ampInfoPath = os.path.join(outDir, shortDetectorName + ".fits") ampTable.writeFits(ampInfoPath)
camConfig.transformDict = tmc def makeDir(dirPath, doClobber=False): """Make a directory; if it exists then clobber or fail, depending on doClobber @param[in] dirPath: path of directory to create @param[in] doClobber: what to do if dirPath already exists: if True and dirPath is a dir, then delete it and recreate it, else raise an exception @throw RuntimeError if dirPath exists and doClobber False """ if os.path.exists(dirPath): if doClobber and os.path.isdir(dirPath): print("Clobbering directory %r" % (dirPath,)) shutil.rmtree(dirPath) else: raise RuntimeError("Directory %r exists" % (dirPath,)) print("Creating directory %r" % (dirPath,)) os.makedirs(dirPath) # write data products outDir = args.OutputDir makeDir(dirPath=outDir, doClobber=args.clobber) camConfigPath = os.path.join(outDir, "camera.py") camConfig.save(camConfigPath) for detectorName, ampTable in ampTableDict.items(): shortDetectorName = DecamMapper.getShortCcdName(detectorName) ampInfoPath = os.path.join(outDir, shortDetectorName + ".fits") ampTable.writeFits(ampInfoPath)
def getButler(datadir): bf = dafPersist.ButlerFactory( mapper=DecamMapper(root=os.path.join(datadir, "DATA"), calibRoot=os.path.join(datadir, "CALIB"))) return bf.create()
description="Convert a DECam crosstalk file into LSST CrosstalkCalibs." ) parser.add_argument(dest="crosstalkInfile", help="DECam crosstalk file.") parser.add_argument("-v", "--verbose", action="store_true", help="Print data about each detector.") parser.add_argument("-f", "--force", action="store_true", help="Overwrite existing CrosstalkCalibs.") cmd = parser.parse_args() outDict = readFile(crosstalkInfile=cmd.crosstalkInfile) crosstalkDir = DecamMapper.getCrosstalkDir() if os.path.exists(crosstalkDir): if not cmd.force: print("Output directory %r exists; use --force to replace" % (crosstalkDir, )) sys.exit(1) print("Replacing data in crosstalk directory %r" % (crosstalkDir, )) else: print("Creating crosstalk directory %r" % (crosstalkDir, )) os.makedirs(crosstalkDir) for detName in outDict: if cmd.verbose: print( f"{detName}: has crosstalk? {outDict[detName]['hasCrosstalk']}" ) print(f"COEFF:\n{outDict[detName]['coeffs']}")
def setUp(self): self.bf = dafPersist.ButlerFactory(mapper=DecamMapper(root=".")) self.butler = self.bf.create()