示例#1
0
 def fibers_to_exclude(self):
     """                                                                                         
     Args:                                                                                       
         None                                                                                  
     Returns:                                                                                    
         List of excluded fibers from yaml file as a 1D array of intergers                    
         If no excluded fibers, returns None                                                  
     """
     key = 'EXCLUDEFIBERS'
     if not self.haskey(key):
         excluded = np.array([])
     else:
         excluded_str = self.value(key)
         excluded = parse_fibers(excluded_str)
     return excluded
示例#2
0
 def test_parse_fibers(self):
     """
     test the util func parse_fibers
     """
     str1 = '0:10'
     str2 = '1,2,3,4:8'
     str3 = '1..5,6,7,8:10,11-14'
     arr1 = np.array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
     arr2 = np.array([1, 2, 3, 4, 5, 6, 7])
     arr3 = np.array([1, 2, 3, 4, 6, 7, 8, 9, 11, 12, 13])
     for instr, arr in zip([str1, str2, str3], [arr1, arr2, arr3]):
         returned_arr = util.parse_fibers(instr)
         self.assertEqual(len(returned_arr), len(arr))
         for v1, v2 in zip(returned_arr, arr):
             self.assertEqual(int(v1), int(v2))
示例#3
0
 def fiberblacklist(self):
     """
     Args:
         None
     Returns:
         List of blacklisted fibers from yaml file as a 1D array of intergers
         If no blacklisted fibers, returns None
     """
     log = get_logger()
     blacklistkey = "FIBERBLACKLIST"
     if not self.haskey(blacklistkey) and self.haskey("BROKENFIBERS"):
         log.warning(
             "BROKENFIBERS yaml keyword deprecated, please use FIBERBLACKLIST"
         )
         blacklistkey = "BROKENFIBERS"
     if self.haskey(blacklistkey):
         fiberblacklist_str = self.value(blacklistkey)
         fiberblacklist = parse_fibers(fiberblacklist_str)
     else:
         fiberblacklist = np.array([])
     return fiberblacklist
示例#4
0
def main(args=None):

    if args is None:
        args = parse()
    elif isinstance(args, (list, tuple)):
        args = parse(args)

    t0 = time.time()
    log = get_logger()

    # guess if it is a preprocessed or a raw image
    hdulist = fits.open(args.image)
    is_input_preprocessed = ("IMAGE" in hdulist) & ("IVAR" in hdulist)
    primary_header = hdulist[0].header
    input_has_fibermap = ("FIBERMAP" in hdulist)
    hdulist.close()

    if is_input_preprocessed:
        image = read_image(args.image)
    else:
        if args.camera is None:
            print(
                "ERROR: Need to specify camera to open a raw fits image (with all cameras in different fits HDUs)"
            )
            print(
                "Try adding the option '--camera xx', with xx in {brz}{0-9}, like r7,  or type 'desi_qproc --help' for more options"
            )
            sys.exit(12)
        image = read_raw(args.image, args.camera, fill_header=[
            1,
        ])

    if args.auto:
        log.debug("AUTOMATIC MODE")
        try:
            night = image.meta['NIGHT']
            if not 'EXPID' in image.meta:
                if 'EXPNUM' in image.meta:
                    log.warning('using EXPNUM {} for EXPID'.format(
                        image.meta['EXPNUM']))
                    image.meta['EXPID'] = image.meta['EXPNUM']
            expid = image.meta['EXPID']
        except KeyError as e:
            log.error(
                "Need at least NIGHT and EXPID (or EXPNUM) to run in auto mode. Retry without the --auto option."
            )
            log.error(str(e))
            sys.exit(12)

        indir = os.path.dirname(args.image)
        if args.fibermap is None:
            #- first check if input image has a fibermap
            if input_has_fibermap:
                log.debug('auto-mode: using FIBERMAP in input image file')
                args.fibermap = args.image
            else:
                filename = '{}/fibermap-{:08d}.fits'.format(indir, expid)
                if os.path.isfile(filename):
                    log.debug(
                        "auto-mode: found a fibermap, {}, using it!".format(
                            filename))
                    args.fibermap = filename

        if args.output_preproc is None:
            if not is_input_preprocessed:
                args.output_preproc = '{}/preproc-{}-{:08d}.fits'.format(
                    args.auto_output_dir, args.camera.lower(), expid)
                log.debug("auto-mode: will write preproc in " +
                          args.output_preproc)
            else:
                log.debug(
                    "auto-mode: will not write preproc because input is a preprocessed image"
                )

        if args.auto_output_dir != '.':
            if not os.path.isdir(args.auto_output_dir):
                log.debug("auto-mode: creating directory " +
                          args.auto_output_dir)
                os.makedirs(args.auto_output_dir)

    if args.output_preproc is not None:
        write_image(args.output_preproc, image)

    cfinder = None

    if args.psf is None:
        if cfinder is None:
            cfinder = CalibFinder([image.meta, primary_header])
        args.psf = cfinder.findfile("PSF")
        log.info(" Using PSF {}".format(args.psf))

    tset = read_xytraceset(args.psf)

    # add fibermap
    if args.fibermap:
        if os.path.isfile(args.fibermap):
            fibermap = read_fibermap(args.fibermap)
        elif hasattr(image, 'fibermap') and image.fibermap is not None:
            log.info('Using fibermap from preproc')
            fibermap = image.fibermap
        else:
            log.error("no fibermap file {}".format(args.fibermap))
            fibermap = None
    else:
        fibermap = None

    if "OBSTYPE" in image.meta:
        obstype = image.meta["OBSTYPE"].upper()
        image.meta["OBSTYPE"] = obstype  # make sure it's upper case
        qframe = None
    else:
        log.warning("No OBSTYPE keyword, trying to guess ...")
        qframe = qproc_boxcar_extraction(tset,
                                         image,
                                         width=args.width,
                                         fibermap=fibermap)
        input_flavor = None
        if "FLAVOR" in image.meta: input_flavor = image.meta["FLAVOR"]
        obstype = check_qframe_flavor(qframe,
                                      input_flavor=input_flavor).upper()
        image.meta["OBSTYPE"] = obstype

    log.info("OBSTYPE = '{}'".format(obstype))

    if args.auto:

        # now set the things to do
        if obstype == "SKY" or obstype == "TWILIGHT" or obstype == "SCIENCE":

            args.shift_psf = True
            args.output_psf = '{}/psf-{}-{:08d}.fits'.format(
                args.auto_output_dir, args.camera, expid)
            args.output_rawframe = '{}/qframe-{}-{:08d}.fits'.format(
                args.auto_output_dir, args.camera, expid)
            args.apply_fiberflat = True
            args.skysub = True
            args.output_skyframe = '{}/qsky-{}-{:08d}.fits'.format(
                args.auto_output_dir, args.camera, expid)
            args.fluxcalib = True
            args.outframe = '{}/qcframe-{}-{:08d}.fits'.format(
                args.auto_output_dir, args.camera, expid)

        elif obstype == "ARC" or obstype == "TESTARC":

            args.shift_psf = True
            args.output_psf = '{}/psf-{}-{:08d}.fits'.format(
                args.auto_output_dir, args.camera, expid)
            args.output_rawframe = '{}/qframe-{}-{:08d}.fits'.format(
                args.auto_output_dir, args.camera, expid)
            args.compute_lsf_sigma = True

        elif obstype == "FLAT" or obstype == "TESTFLAT":
            args.shift_psf = True
            args.output_psf = '{}/psf-{}-{:08d}.fits'.format(
                args.auto_output_dir, args.camera, expid)
            args.output_rawframe = '{}/qframe-{}-{:08d}.fits'.format(
                args.auto_output_dir, args.camera, expid)
            args.compute_fiberflat = '{}/qfiberflat-{}-{:08d}.fits'.format(
                args.auto_output_dir, args.camera, expid)

    if args.shift_psf:

        # using the trace shift script
        if args.auto:
            options = option_list({
                "psf":
                args.psf,
                "image":
                "dummy",
                "outpsf":
                "dummy",
                "continuum": ((obstype == "FLAT") | (obstype == "TESTFLAT")),
                "sky": ((obstype == "SCIENCE") | (obstype == "SKY"))
            })
        else:
            options = option_list({
                "psf": args.psf,
                "image": "dummy",
                "outpsf": "dummy"
            })
        tmp_args = trace_shifts_script.parse(options=options)
        tset = trace_shifts_script.fit_trace_shifts(image=image, args=tmp_args)

    qframe = qproc_boxcar_extraction(tset,
                                     image,
                                     width=args.width,
                                     fibermap=fibermap)

    if tset.meta is not None:
        # add traceshift info in the qframe, this will be saved in the qframe header
        if qframe.meta is None:
            qframe.meta = dict()
        for k in tset.meta.keys():
            qframe.meta[k] = tset.meta[k]

    if args.output_rawframe is not None:
        write_qframe(args.output_rawframe, qframe)
        log.info("wrote raw extracted frame in {}".format(
            args.output_rawframe))

    if args.compute_lsf_sigma:
        tset = process_arc(qframe, tset, linelist=None, npoly=2, nbins=2)

    if args.output_psf is not None:
        for k in qframe.meta:
            if k not in tset.meta:
                tset.meta[k] = qframe.meta[k]
        write_xytraceset(args.output_psf, tset)

    if args.compute_fiberflat is not None:
        fiberflat = qproc_compute_fiberflat(qframe)
        #write_qframe(args.compute_fiberflat,qflat)
        write_fiberflat(args.compute_fiberflat, fiberflat, header=qframe.meta)
        log.info("wrote fiberflat in {}".format(args.compute_fiberflat))

    if args.apply_fiberflat or args.input_fiberflat:

        if args.input_fiberflat is None:
            if cfinder is None:
                cfinder = CalibFinder([image.meta, primary_header])
            try:
                args.input_fiberflat = cfinder.findfile("FIBERFLAT")
            except KeyError as e:
                log.error("no FIBERFLAT for this spectro config")
                sys.exit(12)
        log.info("applying fiber flat {}".format(args.input_fiberflat))
        flat = read_fiberflat(args.input_fiberflat)
        qproc_apply_fiberflat(qframe, flat)

    if args.skysub:
        log.info("sky subtraction")
        if args.output_skyframe is not None:
            skyflux = qproc_sky_subtraction(qframe, return_skymodel=True)
            sqframe = QFrame(qframe.wave,
                             skyflux,
                             np.ones(skyflux.shape),
                             fibermap=fibermap)
            write_qframe(args.output_skyframe, sqframe)
            log.info("wrote sky model in {}".format(args.output_skyframe))
        else:
            qproc_sky_subtraction(qframe)

    if args.fluxcalib:
        if cfinder is None:
            cfinder = CalibFinder([image.meta, primary_header])
        # check for flux calib
        if cfinder.haskey("FLUXCALIB"):
            fluxcalib_filename = cfinder.findfile("FLUXCALIB")
            fluxcalib = read_average_flux_calibration(fluxcalib_filename)
            log.info("read average calib in {}".format(fluxcalib_filename))
            if "SEEING" in qframe.meta:
                seeing = qframe.meta["SEEING"]
            else:
                log.warning("no SEEING information")
                seeing = 1
            if "AIRMASS" in qframe.meta:
                airmass = qframe.meta["AIRMASS"]
            else:
                log.warning("no AIRMASS information")
                airmass = 1
            exptime = qframe.meta["EXPTIME"]
            exposure_calib = fluxcalib.value(seeing=seeing, airmass=airmass)
            for q in range(qframe.nspec):
                fiber_calib = np.interp(qframe.wave[q], fluxcalib.wave,
                                        exposure_calib) * exptime
                inv_calib = (fiber_calib > 0) / (fiber_calib +
                                                 (fiber_calib == 0))
                qframe.flux[q] *= inv_calib
                qframe.ivar[q] *= fiber_calib**2 * (fiber_calib > 0)

            # add keyword in header giving the calibration factor applied at a reference wavelength
            band = qframe.meta["CAMERA"].upper()[0]
            if band == "B":
                refwave = 4500
            elif band == "R":
                refwave = 6500
            else:
                refwave = 8500
            calvalue = np.interp(refwave, fluxcalib.wave,
                                 exposure_calib) * exptime
            qframe.meta["CALWAVE"] = refwave
            qframe.meta["CALVALUE"] = calvalue
        else:
            log.error(
                "Cannot calibrate fluxes because no FLUXCALIB keywork in calibration files"
            )

    if args.fibers is not None:
        fibers = parse_fibers(args.fibers)
        ii = np.arange(qframe.fibers.size)[np.in1d(qframe.fibers, fibers)]
        if ii.size == 0:
            log.error("no such fibers in frame,")
            log.error("fibers are in range [{}:{}]".format(
                qframe.fibers[0], qframe.fibers[-1] + 1))
            sys.exit(12)
        qframe = qframe[ii]

    if args.outframe is not None:
        write_qframe(args.outframe, qframe)
        log.info("wrote {}".format(args.outframe))

    t1 = time.time()
    log.info("all done in {:3.1f} sec".format(t1 - t0))

    if args.plot:
        log.info("plotting {} spectra".format(qframe.wave.shape[0]))

        import matplotlib.pyplot as plt
        fig = plt.figure()
        for i in range(qframe.wave.shape[0]):
            j = (qframe.ivar[i] > 0)
            plt.plot(qframe.wave[i, j], qframe.flux[i, j])
        plt.grid()
        plt.xlabel("wavelength")
        plt.ylabel("flux")
        plt.show()