Source code for kcwidrp.scripts.wb

#!/usr/bin/env python
import sys
if sys.version_info[0] > 2:
    from astropy.io import fits as pf
else:
    import pyfits as pf


[docs]def wb_main(): """ Generate summary log and group list files for BLUE channel images. Call get_log_string to create summary entry for each image and group them according to processing group. Write out unique processing group lists in \*.txt files. These files can be input to the pipeline with the -l command line parameter to allow processing of groups one at a time. For example, 2x2 Blue biases taken with the TUP amp configuration in slow readout with gainmul 10 will end up in the file bias2x2TUP010_0.txt. A master bias can be created by issuing the following command: >>> reduce_kcwi -b -l bias2x2TUP010_0.txt These group files are generated for biases, darks, continuum bars, arcs, flats, and all objects. The filenames are all appended with the last four characters of the STATEID header keyword, so identical configurations from different states can be distinguished. Always good to type out the list file before processing it. Examples: >>> wb kb*.fits > whatb.list This will generate a summary log file along with associated group list files that can be used as inputs to the `reduce_kcwi` command with the `-l` parameter. An example of the resulting \*.txt files is below:: SN2023ixf2x2MedKBlueBL4500_75fe.txt bias2x2TUP010_0.txt allb.txt cbars2x2MedKBlueBL_4500_0.7_75fe.txt arcs2x2MedKBlueBLFeAr4500_10.0_75fe.txt cflat2x2MedKBlueBL_4500_0.7_75fe.txt arcs2x2MedKBlueBLThAr4500_20.0_75fe.txt dflat2x2MedKBlueBL_4500_14.0_75fe.txt bd26d26062x2MedKBlueBL4500_75fe.txt One can proceed through processing steps like this: >>> reduce_kcwi -b -l bias2x2TUP010_0.txt >>> reduce_kcwi -b -l cbars2x2MedKBlueBL_4500_0.7_75fe.txt >>> reduce_kcwi -b -l arcs2x2MedKBlueBLThAr4500_20.0_75fe.txt >>> reduce_kcwi -b -l cflat2x2MedKBlueBL_4500_0.7_75fe.txt >>> reduce_kcwi -b -l bd26d26062x2MedKBlueBL4500_75fe.txt >>> reduce_kcwi -b -l SN2023ixf2x2MedKBlueBL4500_75fe.txt """ import sys if len(sys.argv) < 2: print("Usage - wb <fspec>") else: configs = [] fnames = {"allb": []} for ifl in sys.argv[1:]: logstr, cfgstr, lsfn = get_log_string(ifl, batch=True) print(logstr) fnames['allb'].append(ifl) if lsfn: if lsfn in fnames: fnames[lsfn].append(ifl) else: fnames[lsfn] = [ifl] if cfgstr: configs.append(cfgstr) # Unique configs uconfigs = sorted(set(configs)) print("Number of unique configurations = %d" % len(uconfigs)) for c in uconfigs: print(c) for cal in fnames: with open(cal+".txt", 'w') as cal_list: for f in fnames[cal]: cal_list.write(f + "\n")
def get_cal_list_file(hdr): """ Return list file name given configuration in header. Generates the group file name apropriate for the input image header. Args: hdr (FITS header): the current image header :returns: (str): group filename :meta private: """ fpre = {"ARCLAMP": "arcs", "CONTBARS": "cbars", "FLATLAMP": "cflat", "DOMEFLAT": "dflat", "TWIFLAT": "tflat"} imtype = hdr['IMTYPE'] lfname = None if imtype in fpre: lfname = fpre[imtype] lfname += hdr['BINNING'].replace(',', 'x') lfname += hdr['IFUNAM'][:3] lfname += hdr['BFILTNAM'] lfname += hdr['BGRATNAM'] if 'arcs' in lfname: if 'FeAr' in hdr['ILLUME']: lfname += 'FeAr' else: lfname += 'ThAr' else: lfname += '_' lfname += "%.0f" % hdr['BCWAVE'] lfname += "_%.1f" % hdr['EXPTIME'] lfname += "_" + hdr['CONFIGID'] elif 'BIAS' in imtype: lfname = 'bias' lfname += hdr['BINNING'].replace(',', 'x') lfname += hdr['AMPMODE'] lfname += str(hdr['CCDMODE']) lfname += str(hdr['GAINMUL']) lfname += "_" + hdr['CONFIGID'] elif 'DARK' in imtype: lfname = 'dark' lfname += hdr['BINNING'].replace(',', 'x') lfname += hdr['AMPMODE'] lfname += str(hdr['CCDMODE']) lfname += str(hdr['GAINMUL']) lfname += "_%.1f" % hdr['EXPTIME'] lfname += "_" + hdr['CONFIGID'] elif 'OBJECT' in imtype: lfname = hdr['TARGNAME'] lfname += hdr['BINNING'].replace(',', 'x') lfname += hdr['IFUNAM'][:3] lfname += hdr['BFILTNAM'] lfname += hdr['BGRATNAM'] lfname += "%.0f" % hdr['BCWAVE'] lfname += "_" + hdr['CONFIGID'] return lfname def get_log_string(ifile, batch=False): """ Generate log entry from BLUE FITS header keywords. Attempt to encapsulate the instrument configuration for each image by summarizing FITS header keyword values tersely. Args: ifile (str): filename of FITS image to summarize batch (bool): set to ``True`` for an abreviated record. Defaults to ``False``. :returns: (str): Configuration summary string for the input FITS image file. :meta private: """ try: ff = pf.open(ifile) except IOError: print("***ERROR*** empty or corrupt fits file: %s" % ifile) return None, None header = ff[0].header header['FNAME'] = ifile if 'CAMERA' in header: if 'BLUE' in header['CAMERA'].upper(): is_bias = False if 'OFNAME' not in header: header['OFNAME'] = ifile if 'STATEID' not in header: header['CONFIGID'] = '----' else: header['CONFIGID'] = header['STATEID'][-4:] if 'AMPMODE' not in header: header['AMPMODE'] = '-' if 'BINNING' not in header: header['BINNING'] = '-' if 'CCDMODE' not in header: header['CCDMODE'] = -1 if 'GAINMUL' not in header: header['GAINMUL'] = -1 if 'NUMOPEN' not in header: header['NUMOPEN'] = -1 if 'XPOSURE' not in header: header['XPOSURE'] = -1. if 'AIRMASS' not in header: header['AIRMASS'] = -1. if 'TELAPSE' not in header: header['TELAPSE'] = -1. if 'BFILTNAM' not in header: header['BFILTNAM'] = '-' if 'BGRATNAM' not in header: header['BGRATNAM'] = '-' if 'BGROTNAM' not in header: header['BGROTNAM'] = '-' if 'BCWAVE' not in header: header['BCWAVE'] = -1. if 'CALMNAM' not in header: header['CALMNAM'] = '-' if 'CALPNAM' not in header: header['CALPNAM'] = '-' if 'CALLANG' not in header: header['CALLANG'] = -1. if 'BARTANG' not in header: header['BARTANG'] = -1. if 'BNASNAM' not in header: header['BNASNAM'] = '-' if 'BFOCMM' not in header: header['BFOCMM'] = -1. if 'CALTYPE' not in header: header['CALTYPE'] = '-' if 'IFUNAM' not in header: header['IFUNAM'] = '-' else: header['IFUNAM'] = header['IFUNAM'][:3] if 'OBJECT' not in header: header['OBJECT'] = '-' if 'TARGNAME' not in header: header['TARGNAME'] = '-' if 'CALXNAM' not in header: header['CALXNAM'] = '-' if 'object' not in header['CALTYPE']: header['OBJECT'] = header['CALXNAM'] if header['TELAPSE'] > header['XPOSURE']: header['EXPTIME'] = header['TELAPSE'] else: header['EXPTIME'] = header['XPOSURE'] if header['EXPTIME'] <= 0.: is_bias = True header['ILLUME'] = '-' try: if header['LMP0STAT'] == 1: if header['LMP0SHST'] == 1: header['ILLUME'] = header['LMP0NAM'] if header['LMP1STAT'] == 1: if header['LMP1SHST'] == 1: header['ILLUME'] = header['LMP1NAM'] if header['LMP2STAT'] == 1: if header['LMP2SHST'] == 1: header['ILLUME'] = header['LMP2NAM'] if header['LMP3STAT'] == 1: header['ILLUME'] = header['LMP3NAM'][0:6] if 'object' in header['CALTYPE']: if 'on' in header['FLSPECTR'] or 'on' in header['FLIMAGIN']: header['ILLUME'] = 'DOME' if not batch: header['OBJECT'] = 'DOME' if 'BIAS' in header['IMTYPE']: if not is_bias: header['IMTYPE'] = 'DARK' if 'DARK' in header['IMTYPE']: if is_bias: header['IMTYPE'] = 'BIAS' if not batch: if 'object' not in header['CALTYPE']: header['OBJECT'] = header['OBJECT'] + header['ILLUME'] except KeyError: pass try: lstring = "%(OFNAME)19s %(CONFIGID)4s (%(AMPMODE)3s/%(BINNING)3s/%(CCDMODE)1d/" \ "%(GAINMUL)2d/%(NUMOPEN)2d/%(EXPTIME)6.1f s), (%(IFUNAM)3s/" \ "%(BFILTNAM)5s/%(BGRATNAM)4s/%(BGROTNAM)9s dg/" \ "%(BCWAVE)6.1f/%(CALMNAM)s/%(CALPNAM)5s/%(CALLANG)5.1f dg), " \ "(%(BARTANG)5.1f/%(BNASNAM)4s/%(BFOCMM)6.3f) %(AIRMASS)5.3f: %(IMTYPE)7s/" \ "%(ILLUME)6s/%(TARGNAME)s:%(OBJECT)s" % header except: lstring = "%19s : ?" % ifile if header['EXPTIME'] <= 0.0: cstr = "%(BINNING)3s:%(AMPMODE)3s:%(CCDMODE)1d:%(GAINMUL)2d:BIAS" % \ header else: if batch: cstr = "%(BINNING)3s:%(BFILTNAM)s:%(BGRATNAM)s:%(IFUNAM)s:%(BCWAVE).1f" \ % header else: cstr = "%(BINNING)3s:%(BFILTNAM)s:%(BGRATNAM)s:%(IFUNAM)s:%(BCWAVE).1f:" \ "%(EXPTIME)6.1f:%(OBJECT)s" % header lfn = get_cal_list_file(header) else: lstring = "%19s : NOT a BLUE image!" % ifile cstr = None lfn = None else: if not batch: print("ERROR - Camera can not be determined.") lstring = "%19s : No CAMERA keyword!" % ifile cstr = None lfn = None return lstring, cstr, lfn if __name__ == '__main__': wb_main()