Skip to content

Commit

Permalink
Merge pull request #8 from LowellObservatory/issue_7_fix
Browse files Browse the repository at this point in the history
Bugfix for Issue #7
  • Loading branch information
tbowers7 authored Dec 11, 2023
2 parents 94d6dce + 15f65ac commit 25bb4ab
Show file tree
Hide file tree
Showing 3 changed files with 136 additions and 118 deletions.
7 changes: 5 additions & 2 deletions doc/help/scrub_deveny_pickup.rst
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,11 @@
options:
-h, --help show this help message and exit
--proc_dir PROC_DIR Path to the directory containing the .pypeit file used to
process `file` (ldt_deveny_?) (default: None)
--proc_dir PROC_DIR Path to the directory above that which contains the
.pypeit file used to process `file` (i.e., the directory
above ldt_deveny_?) -- use only if `-r` was used in the
call to `pypeit_setup`. (default: current working
directory)
--overwrite_raw Overwrite the raw file rather than create a new file with
the '_scrub' suffix (default: False)
-d, --diagnostics Output additional information and plots during the
Expand Down
31 changes: 16 additions & 15 deletions obstools/scrub_deveny_pickup.py
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@
# Narrative Functions ========================================================#
def iterative_pypeit_clean(
filename: pathlib.Path,
proc_dir: str | pathlib.Path = None,
proc_dir: pathlib.Path = None,
overwrite_raw: bool = False,
diagnostics: bool = False,
no_refit: bool = False,
Expand All @@ -100,7 +100,7 @@ def iterative_pypeit_clean(
----------
filename : :obj:`~pathlib.Path`
The name of the file to clean
proc_dir : :obj:`str` or :obj:`~pathlib.Path`, optional
proc_dir : :obj:`~pathlib.Path`, optional
The location of the PypeIt-processed images, if not ``./ldt_deveny_?/``
(Default: None)
overwrite_raw : :obj:`bool`, optional
Expand All @@ -123,17 +123,16 @@ def iterative_pypeit_clean(
# comprehension searches in each possible 'instrument setup' directory
# Check that the `spec2d` file actually exists and print a helpful
# message if it doesn't.
pyp_dir = (
[proc_dir]
if proc_dir is not None
else sorted(filename.parent.glob("ldt_deveny_?"))
)
pyp_dir = sorted(proc_dir.resolve().glob("ldt_deveny_?"))

try:
# Look for the spec2d file
spec2d_file = [
next(d.joinpath("Science").glob(f"spec2d_{filename.stem}-*.fits"))
for d in pyp_dir
][0]
spec2d_file = utils.flatten_comprehension(
[
sorted(d.joinpath("Science").glob(f"spec2d_{filename.stem}-*.fits"))
for d in pyp_dir
]
)[0]
except (StopIteration, IndexError):
# And... fail.
msgs.warn(
Expand Down Expand Up @@ -1643,9 +1642,11 @@ def get_parser(cls, width=None):
parser.add_argument(
"--proc_dir",
type=str,
default=None,
help="Path to the directory containing the .pypeit file used to "
"process `file` (ldt_deveny_?)",
default="current working directory",
help="Path to the directory above that which contains the .pypeit "
"file used to process `file` (i.e., the directory above "
"ldt_deveny_?) -- use only if `-r` was used in the call to "
"`pypeit_setup`.",
)
parser.add_argument(
"--overwrite_raw",
Expand Down Expand Up @@ -1682,7 +1683,7 @@ def main(args):
for file in args.file:
iterative_pypeit_clean(
pathlib.Path(file).resolve(),
proc_dir=args.proc_dir,
proc_dir=pathlib.Path(args.proc_dir),
overwrite_raw=args.overwrite_raw,
diagnostics=args.diagnostics,
no_refit=args.no_refit,
Expand Down
216 changes: 115 additions & 101 deletions obstools/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
import argparse
from functools import reduce
from importlib import resources
import os
import pathlib
import textwrap
import sys
import warnings
Expand Down Expand Up @@ -116,6 +116,24 @@ def first_moment_1d(line):
return np.sum(yy * line) / np.sum(line)


def flatten_comprehension(nested_list: list) -> list:
"""Flatten a single-depth nested list via list comprehension
https://realpython.com/python-flatten-list/
Parameters
----------
nested_list : :obj:`list`
The single-depth nested list to flatten
Returns
-------
:obj:`list`
The flattened list
"""
return [item for row in nested_list for item in row]


def gaussfit(x, y, nterms: int = 3, estimates=None, bounds=None, debug: bool = False):
"""Function similar to IDL's GAUSSFIT
Expand Down Expand Up @@ -496,108 +514,15 @@ def warn_and_return_zeros(return_full: bool, x, xx, yy, order, raise_warn=False)
return [0] * (order + 1)


"""
Implements base classes for use with ``PypeIt`` scripts.
.. include common links, assuming primary doc root is up one directory
.. include:: ../include/links.rst
"""


class SmartFormatter(argparse.HelpFormatter):
r"""
Enable a combination of both fixed-format and wrappable lines to be
formatted for the help statements for command-line arguments used with
:class:`~argparse.ArgumentParser`.
Borrows from
https://stackoverflow.com/questions/3853722/python-argparse-how-to-insert-newline-in-the-help-text
Help strings that use this formatter *must* begin with "R|". If not, the
help string is parsed by the base class.
When parsed by this formatter, the leading "R|" characters are stripped and
the lines to be printed are parsed using :func:`~str.splitlines`. Each resulting
line is wrapped using :func:`~textwrap.wrap`, unless it begins with the characters
"F|", which forces the line to remain unaltered (except for stripping the
leading characters).
For example, if you add an argument like this:
.. code-block:: python
parser.add_argument('-t', '--tell_file', type=str,
help='R|Configuration file to change default telluric parameters. '
'Note that the parameters in this file will be overwritten if '
'you set argument in your terminal. The --tell_file option '
'requires a .tell file with the following format:\n'
'\n'
'F| [tellfit]\n'
'F| objmodel = qso\n'
'F| redshift = 7.6\n'
'F| bal_wv_min_max = 10825,12060\n'
'OR\n'
'F| [tellfit]\n'
'F| objmodel = star\n'
'F| star_type = A0\n'
'F| star_mag = 8.\n'
'OR\n'
'F| [tellfit]\n'
'F| objmodel = poly\n'
'F| polyorder = 3\n'
'F| fit_wv_min_max = 9000.,9500.\n'
'\n')
The result will be (depending on the width of your console):
.. code-block:: console
-t TELL_FILE, --tell_file TELL_FILE
Configuration file to change default telluric
parameters. Note that the parameters in this file
will be overwritten if you set argument in your
terminal. The --tell_file option requires a .tell
file with the following format:
[tellfit]
objmodel = qso
redshift = 7.6
bal_wv_min_max = 10825,12060
OR
[tellfit]
objmodel = star
star_type = A0
star_mag = 8.
OR
[tellfit]
objmodel = poly
polyorder = 3
fit_wv_min_max = 9000.,9500.
class ScriptBase:
"""
Provides a base class for all scripts.
def _split_lines(self, text, width):
"""
Split the provided text into width constrained lines.
See the class description for formatting instructions.
"""
if text.startswith("R|"):
lines = text[2:].splitlines()
for i in range(len(lines)):
if lines[i].startswith("F|"):
lines[i] = [lines[i][2:]]
elif len(lines[i]) == 0:
lines[i] = [" "]
else:
lines[i] = textwrap.wrap(lines[i], width)
return reduce(list.__add__, lines)
return super()._split_lines(text, width)
Implements base classes for use with ``PypeIt`` scripts.
.. include common links, assuming primary doc root is up one directory
.. include:: ../include/links.rst
class ScriptBase:
"""
Provides a base class for all scripts.
"""

@classmethod
Expand Down Expand Up @@ -647,15 +572,14 @@ def _fill_parser_cwd(parser):
"""
for action in parser._actions:
if action.default == "current working directory":
action.default = os.getcwd()
action.default = pathlib.Path.cwd()

# Base classes should override this
@staticmethod
def main(args):
"""
Execute the script.
"""
pass

@classmethod
def get_parser(
Expand Down Expand Up @@ -701,3 +625,93 @@ def get_parser(
description=description,
formatter_class=lambda prog: formatter(prog, width=width),
)


class SmartFormatter(argparse.HelpFormatter):
r"""
Enable a combination of both fixed-format and wrappable lines to be
formatted for the help statements for command-line arguments used with
:class:`~argparse.ArgumentParser`.
Borrows from
https://stackoverflow.com/questions/3853722/python-argparse-how-to-insert-newline-in-the-help-text
Help strings that use this formatter *must* begin with "R|". If not, the
help string is parsed by the base class.
When parsed by this formatter, the leading "R|" characters are stripped and
the lines to be printed are parsed using :func:`~str.splitlines`. Each resulting
line is wrapped using :func:`~textwrap.wrap`, unless it begins with the characters
"F|", which forces the line to remain unaltered (except for stripping the
leading characters).
For example, if you add an argument like this:
.. code-block:: python
parser.add_argument('-t', '--tell_file', type=str,
help='R|Configuration file to change default telluric parameters. '
'Note that the parameters in this file will be overwritten if '
'you set argument in your terminal. The --tell_file option '
'requires a .tell file with the following format:\n'
'\n'
'F| [tellfit]\n'
'F| objmodel = qso\n'
'F| redshift = 7.6\n'
'F| bal_wv_min_max = 10825,12060\n'
'OR\n'
'F| [tellfit]\n'
'F| objmodel = star\n'
'F| star_type = A0\n'
'F| star_mag = 8.\n'
'OR\n'
'F| [tellfit]\n'
'F| objmodel = poly\n'
'F| polyorder = 3\n'
'F| fit_wv_min_max = 9000.,9500.\n'
'\n')
The result will be (depending on the width of your console):
.. code-block:: console
-t TELL_FILE, --tell_file TELL_FILE
Configuration file to change default telluric
parameters. Note that the parameters in this file
will be overwritten if you set argument in your
terminal. The --tell_file option requires a .tell
file with the following format:
[tellfit]
objmodel = qso
redshift = 7.6
bal_wv_min_max = 10825,12060
OR
[tellfit]
objmodel = star
star_type = A0
star_mag = 8.
OR
[tellfit]
objmodel = poly
polyorder = 3
fit_wv_min_max = 9000.,9500.
"""

def _split_lines(self, text, width):
"""
Split the provided text into width constrained lines.
See the class description for formatting instructions.
"""
if text.startswith("R|"):
lines = text[2:].splitlines()
for i, line in enumerate(lines):
if line.startswith("F|"):
lines[i] = [line[2:]]
elif len(line) == 0:
lines[i] = [" "]
else:
lines[i] = textwrap.wrap(line, width)
return reduce(list.__add__, lines)
return super()._split_lines(text, width)

0 comments on commit 25bb4ab

Please sign in to comment.