Ejemplo n.º 1
0
    def test_run(self):
        opts = {}
        opts["spectrographs"] = "0"
        opts["data"] = self.raw
        opts["redux"] = self.redux
        opts["prod"] = self.prod
        opts["shifter"] = self.shifter
        sopts = option_list(opts)
        sargs = pipe_prod.parse(sopts)
        pipe_prod.main(sargs)

        # modify the options to use our No-op worker
        rundir = io.get_pipe_rundir()
        optfile = os.path.join(rundir, "options.yaml")

        opts = {}
        for step in step_types:
            opts["{}_worker".format(step)] = "Noop"
            opts["{}_worker_opts".format(step)] = {}
            opts[step] = {}
        yaml_write(optfile, opts)

        envfile = os.path.join(rundir, "env.sh")
        with open(envfile, "w") as f:
            f.write("export DESIMODEL={}\n".format(rundir))
            if "PATH" in os.environ:
                f.write("export PATH={}\n".format(os.environ["PATH"]))
            if "PYTHONPATH" in os.environ:
                f.write("export PYTHONPATH={}\n".format(os.environ["PYTHONPATH"]))
            if "LD_LIBRARY_PATH" in os.environ:
                f.write("export LD_LIBRARY_PATH={}\n".format(os.environ["LD_LIBRARY_PATH"]))

        com = ". {}; eval {}".format(envfile, os.path.join(rundir, "scripts", "run_shell_all.sh"))
        print(com)
        sp.call(com, shell=True, env=os.environ.copy())
Ejemplo n.º 2
0
def main(args, comm=None):
    rank = 0
    nproc = 1
    if comm is not None:
        rank = comm.rank
        nproc = comm.size

    # Determine which nights we are using
    nights = None
    if args.nights is not None:
        nights = args.nights.split(",")
    else:
        if rank == 0:
            rawdir = os.path.abspath(specio.rawdata_root())
            nights = []
            nightpat = re.compile(r"\d{8}")
            for root, dirs, files in os.walk(rawdir, topdown=True):
                for d in dirs:
                    nightmat = nightpat.match(d)
                    if nightmat is not None:
                        nights.append(d)
                break
        if comm is not None:
            nights = comm.bcast(nights, root=0)

    # Get the list of exposures for each night
    night_expid = {}
    all_expid = []
    exp_to_night = {}
    if rank == 0:
        for nt in nights:
            night_expid[nt] = specio.get_exposures(nt, raw=True)
            all_expid.extend(night_expid[nt])
            for ex in night_expid[nt]:
                exp_to_night[ex] = nt
    if comm is not None:
        night_expid = comm.bcast(night_expid, root=0)
        all_expid = comm.bcast(all_expid, root=0)
        exp_to_night = comm.bcast(exp_to_night, root=0)

    expids = np.array(all_expid, dtype=np.int32)
    nexp = len(expids)

    # Get the list of cameras
    cams = None
    if args.cameras is not None:
        cams = args.cameras.split(",")
    else:
        cams = []
        for band in ['b', 'r', 'z']:
            for spec in range(10):
                cams.append('{}{}'.format(band, spec))

    # number of cameras
    ncamera = len(cams)

    # check that our communicator is an appropriate size

    if comm is not None:
        if ncamera * args.camera_procs > comm.size:
            if comm.rank == 0:
                print("Communicator size ({}) too small for {} cameras each with {} procs".format(comm.size, ncamera, args.camera_procs), flush=True)
                comm.Abort()

    # create a set of reproducible seeds for each exposure
    np.random.seed(args.seed)
    maxexp = np.max(expids)
    allseeds = np.random.randint(2**32, size=(maxexp+1))
    seeds = allseeds[-nexp:]

    taskproc = ncamera * args.camera_procs

    comm_group = comm
    comm_rank = None
    group = comm.rank
    ngroup = comm.size
    group_rank = 0
    if comm is not None:
        from mpi4py import MPI
        if taskproc > 1:
            ngroup = int(comm.size / taskproc)
            group = int(comm.rank / taskproc)
            group_rank = comm.rank % taskproc
            comm_group = comm.Split(color=group, key=group_rank)
            comm_rank = comm.Split(color=group_rank, key=group)
        else:
            comm_group = MPI.COMM_SELF
            comm_rank = comm

    myexpids = np.array_split(expids, ngroup)[group]

    for ex in myexpids:
        nt = exp_to_night[ex]
        
        # path to raw file
        simspecfile = simio.findfile('simspec', nt, ex)
        rawfile = specio.findfile('raw', nt, ex)
        rawfile = os.path.join(os.path.dirname(simspecfile), rawfile)
        
        # Is this exposure already finished?
        done = True
        if group_rank == 0:
            if not os.path.isfile(rawfile):
                done = False
            if args.preproc:
                for c in cams:
                    pixfile = specio.findfile('pix', night=nt,
                        expid=ex, camera=c)
                    if not os.path.isfile(pixfile):
                        done = False
        if comm_group is not None:
            done = comm_group.bcast(done, root=0)
        if done and not args.overwrite:
            if group_rank == 0:
                print("Skipping completed exposure {:08d} on night {}".format(ex, nt))
            continue

        # Write per-process logs to a separate directory,
        # since there are so many of them.
        logdir = "{}_logs".format(rawfile)
        if group_rank == 0:
            if not os.path.isdir(logdir):
                os.makedirs(logdir)
        if comm_group is not None:
            comm_group.barrier()
        tasklog = os.path.join(logdir, "pixsim")

        with stdouterr_redirected(to=tasklog, comm=comm_group):
            try:
                options = {}
                options["night"] = nt
                options["expid"] = int(ex)
                options["cosmics"] = args.cosmics
                options["seed"] = seeds[ex]
                options["cameras"] = ",".join(cams)
                options["mpi_camera"] = args.camera_procs
                options["verbose"] = args.verbose
                options["preproc"] = args.preproc
                optarray = option_list(options)
                pixargs = pixsim.parse(optarray)
                pixsim.main(pixargs, comm_group)
            except:
                exc_type, exc_value, exc_traceback = sys.exc_info()
                lines = traceback.format_exception(exc_type, exc_value, exc_traceback)
                print("".join(lines), flush=True)
Ejemplo n.º 3
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
    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:
            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)
        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)
        obstype = check_qframe_flavor(
            qframe, input_flavor=image.meta["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))
            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))
            seeing = qframe.meta["SEEING"]
            airmass = qframe.meta["AIRMASS"]
            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"
            )

    fibers = parse_fibers(args.fibers)
    if fibers is None:
        fibers = qframe.flux.shape[0]
    else:
        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()
Ejemplo n.º 4
0
        comm_rank = comm.Split(color=group_rank, key=group)
    else:
        comm_group = MPI.COMM_SELF
        comm_rank = comm

log_root = "newexp_"

task = 0
for nt in nights:
    for fl in flavors:
        tasklog = "{}{}-{:08d}.log".format(log_root, nt, expids[task])
        if task == group:
            with stdouterr_redirected(to=tasklog, comm=comm_group):
                try:
                    options = {}
                    options["program"] = fl
                    options["night"] = nt
                    options["expid"] = expids[task]
                    options["tileid"] = tileids[task]
                    options["seed"] = seeds[task]
                    #options["nproc"] = 1
                    optarray = option_list(options)
                    args = newexp.parse(optarray)
                    newexp.main(args)
                except:
                    exc_type, exc_value, exc_traceback = sys.exc_info()
                    lines = traceback.format_exception(exc_type, exc_value, exc_traceback)
                    print("".join(lines), flush=True)
        task += 1