Skip to content

Instantly share code, notes, and snippets.

@jdavies-st
Last active March 6, 2023 08:47
Show Gist options
  • Save jdavies-st/73c72e416bfe1f00b20c3afe91aec1ff to your computer and use it in GitHub Desktop.
Save jdavies-st/73c72e416bfe1f00b20c3afe91aec1ff to your computer and use it in GitHub Desktop.
pyspextool instrument-based read_fits
from . import extract
from .setup_utils import pyspextool_setup, set_paths, set_instrument
# Is there a reason for absolute imports below and relative imports above?
from pyspextool.instrument_data.spex_dir.spex import read_fits as _read_fits_spex
from pyspextool.instrument_data.uspex_dir.uspex import read_fits as _read_fits_uspex
instrument = None
# query some state variable about the instrument here
if instrument == 'spex':
read_fits = _read_fits_spex
elif instrument == 'uspex':
read_fits = _read_fits_uspex
# But the instrument variale state is set after __init__.py is parsed, and it is only parse once, on package
# import. So the above will not work.
# Instead you want to set up a class. Something like:
class Spex:
def __init__(self, instrument=None):
# self.instrument maintains the state of the class, so it always knows what instrument it is
self.instrument = instrument
def _read_fits_spex(self, file):
pass
def _read_fits_uspex(self, file):
pass
def read_fits(self, file):
if self.instrument == "spex":
return self._read_fits_spex(file)
elif self.instrument == "uspex":
return self._read_fits_uspex(file)
else:
raise RuntimeError("Pick an instrument first")
# Another way you could do it:
class Spex:
def __init__(self, instrument=None):
# self.instrument maintains the state of the class, so it always knows what instrument it is
self.instrument = instrument
def read_fits(self, file):
pass
class USpex(Spex):
def __init__(self, instrument):
super().__init__(instrument)
def read_fits(self, file):
pass
# And then invoke the first class via:
from pyspextool import Spex
ps = Spex("uspex")
ps.read_fits("file.fits")
# or the second case:
from pyspextool import USpex
@jdavies-st
Copy link
Author

@michaelcushing

The other thing you could do is define a function somewhere, say serialization.py:

# serialization.py
from pyspextool.instrument_data.spex_dir.spex import read_fits as _read_fits_spex
from pyspextool.instrument_data.uspex_dir.uspex import read_fits as _read_fits_uspex


def read_fits(file):
    if instrument == "spex":
        return _read_fits_spex(file)
    elif instrument == "uspex":
        return _read_fits_uspex(file)
    else:
        raise RuntimeError("Pick an instrument first")

And then you need to figure out how to set instrument. How does setting the instrument type currently work in your set_instrument() function? Does it set a global variable? Global variables in modules are ugly, but they are possible.

# setup_utils.py

_instrument_name = None


def set_instrument(instrument):
    global _instrument_name

    _instrument_name = instrument

That will set a global state variable _instrument_name in that module, which can then be used or set by any other function. It's a bit ugly, but it would work. Prefixing it with an _ indicates to python that it is private, not public.

Much better would be to protect your state variable inside a class, i.e. with something like self.instrument.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment