Source code for pypeit.scripts.setup

"""
This script generates files to setup a PypeIt run

.. include common links, assuming primary doc root is up one directory
.. include:: ../include/links.rst
"""
import argparse
from IPython import embed

from pypeit.scripts import scriptbase
from pypeit.spectrographs.util import available_spectrographs


[docs] class Setup(scriptbase.ScriptBase):
[docs] @classmethod def get_parser(cls, width=None): parser = super().get_parser(description='Parse data files to construct a pypeit file in ' 'preparation for reduction using \'run_pypeit\'', width=width, default_log_file=True) # TODO: Spectrograph should be a required argument parser.add_argument('-s', '--spectrograph', default=None, type=str, help='A valid spectrograph identifier: {0}'.format( ', '.join(available_spectrographs))) parser.add_argument('-r', '--root', default='current working directory', type=str, nargs='+', help='Root to search for data files. You can provide the top-level ' 'directory (e.g., /data/Kast) or the search string up through ' 'the wildcard (.e.g, /data/Kast/b). Use the --extension option ' 'to set the types of files to search for.') parser.add_argument('-e', '--extension', default=None, help='File extension to use. Must include the period (e.g., ".fits") ' 'and it must be one of the allowed extensions for this ' 'spectrograph. If None, root directory will be searched for ' 'all files with any of the allowed extensions.') parser.add_argument('-d', '--output_path', default='current working directory', help='Path to top-level output directory.') parser.add_argument('-o', '--overwrite', default=False, action='store_true', help='Overwrite any existing files/directories') parser.add_argument('-c', '--cfg_split', default=None, type=str, help='Generate the PypeIt files and folders by input configuration. ' 'To write all unique configurations identifed, use \'all\', ' 'otherwise provide the list of configuration letters; e.g., ' '\'A,B\' or \'B,D,E\' or \'E\'.') parser.add_argument('-b', '--background', default=False, action='store_true', help='Include the background-pair columns for the user to edit') parser.add_argument('-f', '--flexure', default=False, action='store_true', help='Include the manual spatial shift (flexure) column for the user to edit') parser.add_argument('-m', '--manual_extraction', default=False, action='store_true', help='Include the manual extraction column for the user to edit') parser.add_argument('-k', '--keep_bad_frames', default=False, action='store_true', help='Keep all frames, even if they are identified as having ' 'bad/unrecognized configurations that cannot be reduced by ' 'pypeit. (This is the opposite of the --bad_frames option in ' 'pypeit_obslog; i.e., you have to tell pypeit_setup to keep ' 'these frames, whereas you have to tell pypeit_obslog to remove ' 'them.') parser.add_argument('-p', '--param_block_file', default=None, type=str, help='File containing the additional PypeIt user parameters to be ' 'added to the parameter block of the generated reduction file') parser.add_argument('-G', '--gui', default=False, action='store_true', help='Run setup in a GUI') # NOTE: These are only used to prevent updates to some of the automated # document building just based on changes in the pypeit version or the # date. These should *not* show up when users run `pypeit_setup -h` due # to the use of `help=argparse.SUPPRESS`. parser.add_argument('--version_override', type=str, default=None, help=argparse.SUPPRESS) parser.add_argument('--date_override', type=str, default=None, help=argparse.SUPPRESS) return parser
[docs] @classmethod def main(cls, args): import time from pathlib import Path from pypeit import log from pypeit.pypeitsetup import PypeItSetup from pypeit.calibrations import Calibrations if args.spectrograph is None: if args.gui is False: raise IOError('spectrograph is a required argument. Use the -s, --spectrograph ' 'command-line option.') else: # Check that input spectrograph is supported if args.spectrograph not in available_spectrographs: raise ValueError(f'Instrument "{args.spectrograph}" unknown to PypeIt.\n' f'\tOptions are: {", ".join(available_spectrographs)}\n' '\tSelect an available instrument or consult the documentation ' 'on how to add a new instrument.') if args.gui: # Start the GUI from pypeit.setup_gui.controller import start_gui start_gui(args) else: # Initialize the log cls.init_log(args) # Initialize PypeItSetup based on the arguments ps = PypeItSetup.from_file_root(args.root, args.spectrograph, extension=args.extension) # Add any additional user parameters if args.param_block_file is not None: if (user_par_fn := Path(args.param_block_file)).exists(): with open(user_par_fn, 'r', encoding='utf-8') as user_par_fobj: user_cfgs = [l.rstrip() for l in user_par_fobj.readlines()] ps.append_user_cfg(user_cfgs) else: log.warning(f"Could not open param_block file {args.param_block_file}. " "Not adding any additional user parameters to the .pypeit file.") # Run the setup ps.run(setup_only=True, clean_config=not args.keep_bad_frames) # Print selected files output_path = Path(args.output_path).absolute() if args.cfg_split is None: # Output directory is hard-coded to be 'setup_files' output_path /= 'setup_files' if not output_path.exists(): output_path.mkdir(parents=True) # Write the sorted file, sorted_file = output_path / ps.pypeit_file.replace('.pypeit', '.sorted') ps.fitstbl.write_sorted(sorted_file, write_bkg_pairs=args.background, write_manual=args.manual_extraction) # the calib file, calib_file = sorted_file.with_suffix('.calib') caldir = calib_file.parent / ps.par['calibrations']['calib_dir'] Calibrations.association_summary(calib_file, ps.fitstbl, ps.spectrograph, caldir, overwrite=True) # and the obslog file obslog_file = sorted_file.with_suffix('.obslog') header = ['Auto-generated PypeIt Observing Log', f'{0}'.format(time.strftime("%a %d %b %Y %H:%M:%S", time.localtime()))] ps.fitstbl.write(output=obslog_file, columns='pypeit', sort_col='mjd', overwrite=True, header=header) else: if not output_path.exists(): output_path.mkdir(parents=True) # Write the pypeit files. configs = [item.strip() for item in args.cfg_split.split(',')] pypeit_files = ps.fitstbl.write_pypeit(output_path=output_path, cfg_lines=ps.user_cfg, write_bkg_pairs=args.background, write_manual=args.manual_extraction, write_shift = args.flexure, configs=configs, version_override=args.version_override, date_override=args.date_override) # Write the calib file for each written pypeit file. setups = [Path(p).absolute().name.split('.')[0].split('_')[-1] for p in pypeit_files] for i, setup in enumerate(setups): indx = ps.fitstbl.find_configuration(setup) calib_file = Path(pypeit_files[i]).absolute().with_suffix('.calib') caldir = calib_file.parent / ps.par['calibrations']['calib_dir'] Calibrations.association_summary(calib_file, ps.fitstbl, ps.spectrograph, caldir, subset=indx, overwrite=True)