def METHOD_NAME(args=None) :
    if not isinstance(args, argparse.Namespace):
        args = parse(args)
    log=get_logger()
    if args.save_adjustments and ((not args.adjust_lsf) or (not args.adjust_wavelength)) :
        mess="need both options --adjust-wavelength and --adjust-lsf to run with --save-adjustments"
        log.error(mess)
        raise Exception(mess)
    if args.exclude_sky_targetids is not None:
        exclude_sky_targetids=[int(_) for _ in args.exclude_sky_targetids.split(',')]
    else:
        exclude_sky_targetids = None
    if args.override_sky_targetids is not None:
        override_sky_targetids=[int(_) for _ in args.override_sky_targetids.split(',')]
    else:
        override_sky_targetids = None
    log.info("starting")
    # read exposure to load data and get range of spectra
    frame = read_frame(args.infile)
    specmin, specmax = np.min(frame.fibers), np.max(frame.fibers)
    if args.cosmics_nsig>0 : # Reject cosmics
        reject_cosmic_rays_1d(frame,args.cosmics_nsig)
    # read fiberflat
    fiberflat = read_fiberflat(args.fiberflat)
    # apply fiberflat to sky fibers
    apply_fiberflat(frame, fiberflat)
    # load pca corr if set
    if args.pca_corr is not None :
        pcacorr = read_skycorr_pca(args.pca_corr)
    else :
        pcacorr = None
    if args.skygradpca is not None:
        skygradpca = read_skygradpca(args.skygradpca)
    else:
        skygradpca = None
    if args.tpcorrparam is not None:
        tpcorrparam = read_tpcorrparam(args.tpcorrparam)
    else:
        tpcorrparam = None
    # compute sky model
    skymodel = compute_sky(frame,add_variance=(not args.no_extra_variance),\
                           adjust_wavelength=args.adjust_wavelength,\
                           adjust_lsf=args.adjust_lsf,\
                           only_use_skyfibers_for_adjustments=(not args.adjust_with_more_fibers),\
                           pcacorr=pcacorr,fit_offsets=args.fit_offsets,fiberflat=fiberflat,
                           skygradpca=skygradpca, tpcorrparam=tpcorrparam,
                           exclude_sky_targetids=exclude_sky_targetids,
                           override_sky_targetids=override_sky_targetids
    )
    if args.save_adjustments is not None :
        skycorr=SkyCorr(wave=skymodel.wave,dwave=skymodel.dwave,dlsf=skymodel.dlsf,header=skymodel.header)
        write_skycorr(args.save_adjustments,skycorr)
        log.info("wrote {}".format(args.save_adjustments))
    # QA
    if (args.qafile is not None) or (args.qafig is not None):
        log.info("performing skysub QA")
        # Load
        qaframe = load_qa_frame(args.qafile, frame_meta=frame.meta, flavor=frame.meta['FLAVOR'])
        # Run
        qaframe.run_qa('SKYSUB', (frame, skymodel))
        # Write
        if args.qafile is not None:
            write_qa_frame(args.qafile, qaframe)
            log.info("successfully wrote {:s}".format(args.qafile))
        # Figure(s)
        if args.qafig is not None:
            qa_plots.frame_skyres(args.qafig, frame, skymodel, qaframe)
    # record inputs
    frame.meta['IN_FRAME'] = shorten_filename(args.infile)
    frame.meta['FIBERFLT'] = shorten_filename(args.fiberflat)
    # write result
    write_sky(args.outfile, skymodel, frame.meta)
    log.info("successfully wrote %s"%args.outfile)