Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Moves msgs into pypit/__init__.py #310

Merged
merged 39 commits into from
Apr 3, 2018
Merged
Show file tree
Hide file tree
Changes from 37 commits
Commits
Show all changes
39 commits
Select commit Hold shift + click to select a range
65f1a9e
test commit
kbwestfall Mar 5, 2018
ea299d6
removed cython functions touched by pypit_test
kbwestfall Mar 10, 2018
835fbb9
minor comments
kbwestfall Mar 12, 2018
8a2d6c5
removing asserts and print statements for cython substitutions
kbwestfall Mar 22, 2018
11c83a8
remove print statements in arextract.py
kbwestfall Mar 22, 2018
2080274
remove print statements in arproc.py
kbwestfall Mar 22, 2018
807c840
cleaned up filter.py
kbwestfall Mar 22, 2018
b0a121e
move msgs to __init__.py; some restructuring and doc changes
kbwestfall Mar 23, 2018
9e1170a
Merge branch 'initmsgs' into kbwdev
kbwestfall Mar 26, 2018
70efe2a
resolve conflicts with master
kbwestfall Mar 26, 2018
6c59494
resolve conflict
kbwestfall Mar 26, 2018
78d1862
lingering armsgs code
kbwestfall Mar 26, 2018
4e0620b
minor debugging; remove ginga imports from ardebug.py
kbwestfall Mar 26, 2018
959d115
try with version_check defined in setup.py
kbwestfall Mar 27, 2018
e9e686c
setup.py bug
kbwestfall Mar 27, 2018
af68663
bug in setup.py
kbwestfall Mar 27, 2018
2224459
rewrite setup.py
kbwestfall Mar 28, 2018
1263449
add requirements.txt and edited CHANGES.rst
kbwestfall Mar 28, 2018
14c5477
remove import of unicode_literals in setup.py
kbwestfall Mar 28, 2018
c03dd79
add call to cythonize
kbwestfall Mar 28, 2018
e291b98
try without cythonize, but with cython as a setup requirement
kbwestfall Mar 28, 2018
bfb9b6c
attempting to fix imports
kbwestfall Mar 29, 2018
c44aa56
bug fix
kbwestfall Mar 29, 2018
f91a2a4
remove arqa import from init
kbwestfall Mar 29, 2018
1d7e5c2
reorganize imports; move most qa plotting routines to relevant module…
kbwestfall Mar 30, 2018
655dd2f
Merge branch 'impmess' into kbwdev
kbwestfall Mar 30, 2018
a7e4a92
add arclines install
profxj Mar 31, 2018
60f749e
move requirements; add check
profxj Mar 31, 2018
00c0e5d
test fix -- remove chk from setup.py
profxj Mar 31, 2018
2824025
remove Ginga as requirement; arclines branch
profxj Mar 31, 2018
9126794
remove Sphinx (docs only)
profxj Mar 31, 2018
b83a7a5
refactor to remove all of PYPIT
profxj Mar 31, 2018
3550314
refactor with arclines
profxj Mar 31, 2018
11f1d9d
remove html; turn on HTML from msgs; archeck fix
profxj Mar 31, 2018
26d9916
linetools test..
profxj Mar 31, 2018
547d392
still fussing..
profxj Mar 31, 2018
4333401
remove from for arclines..
profxj Mar 31, 2018
0f63cd6
final edits before push
kbwestfall Apr 3, 2018
ad9b2e1
only import set_trace from pdb; remove pyputils import from ginga
kbwestfall Apr 3, 2018
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,7 @@ install:
- git clone git://github.com/astropy/ci-helpers.git
- source ci-helpers/travis/setup_conda_$TRAVIS_OS_NAME.sh
- if [[ $SETUP_CMD != egg_info ]]; then $PIP_INSTALL git+https://github.com/linetools/linetools.git; fi
- if [[ $SETUP_CMD != egg_info ]]; then $PIP_INSTALL git+https://github.com/PYPIT/arclines.git@circular_imports; fi
- conda install numpy
- conda install Cython

Expand Down
4 changes: 4 additions & 0 deletions CHANGES.rst
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,10 @@
* Allowed data sections to be extracted from header information
* Significant refactor of routines related to pypit_setup
* Various small improvements, primarly to handle Gemini/GMOS data [not yet fully supported in PYPIT]
* Removed majority of cython functionality
* Moved logging to be a package object using the main __init__.py file
* Begin to adhere to PEP8 (mostly)
* setup.py rewritten. Modeled after https://github.com/sdss/marvin/blob/master/setup.py . Added requirements.txt with the package versions required.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add:

-- Updates archeck
-- Loads NIST arclines from arclines instead of PYPIT

0.7 (2017-02-07)
----------------
Expand Down
52 changes: 52 additions & 0 deletions pypit/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
"""
pypit package initialization.

The current main purpose of this is to provide package-level globals
that can be imported by submodules.
"""

from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
from __future__ import unicode_literals

# Imports for signal and log handling
import sys
import signal
import warnings

# Set version
__version__ = '0.8.0.dev0'
# TODO: Do we need this? A release should be tied to a date, and the
# date information could be put in the CHANGES.rst
__last_updated__ = '23Mar2018'

# Import and instantiate the logger
from pypit import armsgs
msgs = armsgs.Messages()

# Import the close_qa method so that it can be called when a hard stop
# is requested by the user
# TODO: Is this necessary? As far as I can tell, close_qa() doesn't
# actually close any already opened qa files

# TODO: Causes circular imports
# from pypit.arqa import close_qa

# Send all signals to messages to be dealt with (i.e. someone hits ctrl+c)
def signal_handler(signalnum, handler):
"""
Handle signals sent by the keyboard during code execution
"""
if signalnum == 2:
msgs.info('Ctrl+C was pressed. Ending processes...')
# close_qa(msgs.pypit_file)
msgs.close()
sys.exit()

signal.signal(signal.SIGINT, signal_handler)

# Ignore all warnings given by python
warnings.resetwarnings()
warnings.simplefilter('ignore')

144 changes: 129 additions & 15 deletions pypit/ararc.py
Original file line number Diff line number Diff line change
@@ -1,21 +1,25 @@
from __future__ import (print_function, absolute_import, division, unicode_literals)

import os
import time
import inspect

import numpy as np
from matplotlib import pyplot as plt
from matplotlib import gridspec, font_manager

import arclines
#from arclines.holy.grail import basic, semi_brute, general

from pypit import arpca
from pypit import arparse as settings
from pypit import armsgs
from pypit import msgs
from pypit import arsave
from pypit import arutils
from pypit import ararclines
from pypit import arqa
from matplotlib import pyplot as plt
import os
import time

from pypit import ardebug as debugger

# Logging
msgs = armsgs.get_logger()
from pypit import arcyarc


def detect_lines(slf, det, msarc, censpec=None, MK_SATMASK=False):
Expand Down Expand Up @@ -53,7 +57,6 @@ def detect_lines(slf, det, msarc, censpec=None, MK_SATMASK=False):
The spectrum used to find detections. This spectrum has
had any "continuum" emission subtracted off
"""
from pypit import arcyarc
# Extract a rough spectrum of the arc in each order
msgs.info("Detecting lines")
msgs.info("Extracting an approximate arc spectrum at the centre of the chip")
Expand Down Expand Up @@ -548,7 +551,8 @@ def simple_calib(slf, det, get_poly=False):
xrej=xrej, yrej=yrej, mask=mask, spec=yprep, nrej=aparm['nsig_rej_final'],
shift=0., tcent=tcent)
# QA
arqa.arc_fit_qa(slf, final_fit)
# arqa.arc_fit_qa(slf, final_fit)
arc_fit_qa(slf, final_fit)
# RMS
rms_ang = arutils.calc_fit_rms(xfit, yfit, fit, aparm['func'], minv=fmin, maxv=fmax)
wave = arutils.func_val(fit, np.arange(slf._msarc[det-1].shape[0])/float(slf._msarc[det-1].shape[0]),
Expand All @@ -574,22 +578,22 @@ def calib_with_arclines(slf, det, get_poly=False, use_method="general"):
final_fit : dict
Dict of fit info
"""
from arclines.holy.grail import basic, semi_brute, general
# Parameters (just for convenience)
aparm = slf._arcparam[det-1]
# Extract the arc
msgs.work("Detecting lines")
tampl, tcent, twid, w, satsnd, spec = detect_lines(slf, det, slf._msarc[det-1])

if use_method == "semi-brute":
best_dict, final_fit = semi_brute(spec, aparm['lamps'], aparm['wv_cen'], aparm['disp'], fit_parm=aparm, min_ampl=aparm['min_ampl'])
best_dict, final_fit = arclines.holy.grail.semi_brute(spec, aparm['lamps'], aparm['wv_cen'], aparm['disp'], fit_parm=aparm, min_ampl=aparm['min_ampl'])
elif use_method == "basic":
stuff = basic(spec, aparm['lamps'], aparm['wv_cen'], aparm['disp'])
stuff = arclines.holy.grail.basic(spec, aparm['lamps'], aparm['wv_cen'], aparm['disp'])
status, ngd_match, match_idx, scores, final_fit = stuff
else:
# Now preferred
best_dict, final_fit = general(spec, aparm['lamps'], fit_parm=aparm, min_ampl=aparm['min_ampl'])
arqa.arc_fit_qa(slf, final_fit)
best_dict, final_fit = arclines.holy.grail.general(spec, aparm['lamps'], fit_parm=aparm, min_ampl=aparm['min_ampl'])
# arqa.arc_fit_qa(slf, final_fit)
arc_fit_qa(slf, final_fit)
#
return final_fit

Expand Down Expand Up @@ -661,3 +665,113 @@ def new_saturation_mask(a, satlevel):

return mask.astype(int)


def arc_fit_qa(slf, fit, outfile=None, ids_only=False, title=None):
"""
QA for Arc spectrum

Parameters
----------
fit : Wavelength fit
arc_spec : ndarray
Arc spectrum
outfile : str, optional
Name of output file
"""

plt.rcdefaults()
plt.rcParams['font.family']= 'times new roman'

# Grab the named of the method
method = inspect.stack()[0][3]
# Outfil
if outfile is None:
outfile = arqa.set_qa_filename(slf.setup, method)
#
arc_spec = fit['spec']

# Begin
if not ids_only:
plt.figure(figsize=(8, 4.0))
plt.clf()
gs = gridspec.GridSpec(2, 2)
idfont = 'xx-small'
else:
plt.figure(figsize=(11, 8.5))
plt.clf()
gs = gridspec.GridSpec(1, 1)
idfont = 'small'

# Simple spectrum plot
ax_spec = plt.subplot(gs[:,0])
ax_spec.plot(np.arange(len(arc_spec)), arc_spec)
ymin, ymax = 0., np.max(arc_spec)
ysep = ymax*0.03
for kk, x in enumerate(fit['xfit']*fit['xnorm']):
yline = np.max(arc_spec[int(x)-2:int(x)+2])
# Tick mark
ax_spec.plot([x,x], [yline+ysep*0.25, yline+ysep], 'g-')
# label
ax_spec.text(x, yline+ysep*1.3,
'{:s} {:g}'.format(fit['ions'][kk], fit['yfit'][kk]), ha='center', va='bottom',
size=idfont, rotation=90., color='green')
ax_spec.set_xlim(0., len(arc_spec))
ax_spec.set_ylim(ymin, ymax*1.2)
ax_spec.set_xlabel('Pixel')
ax_spec.set_ylabel('Flux')
if title is not None:
ax_spec.text(0.04, 0.93, title, transform=ax_spec.transAxes,
size='x-large', ha='left')#, bbox={'facecolor':'white'})
if ids_only:
plt.tight_layout(pad=0.2, h_pad=0.0, w_pad=0.0)
plt.savefig(outfile, dpi=800)
plt.close()
return

# Arc Fit
ax_fit = plt.subplot(gs[0, 1])
# Points
ax_fit.scatter(fit['xfit']*fit['xnorm'], fit['yfit'], marker='x')
if len(fit['xrej']) > 0:
ax_fit.scatter(fit['xrej']*fit['xnorm'], fit['yrej'], marker='o',
edgecolor='gray', facecolor='none')
# Solution
xval = np.arange(len(arc_spec))
wave = arutils.func_val(fit['fitc'], xval/fit['xnorm'], 'legendre',
minv=fit['fmin'], maxv=fit['fmax'])
ax_fit.plot(xval, wave, 'r-')
xmin, xmax = 0., len(arc_spec)
ax_fit.set_xlim(xmin, xmax)
ymin,ymax = np.min(wave)*.95, np.max(wave)*1.05
ax_fit.set_ylim(np.min(wave)*.95, np.max(wave)*1.05)
ax_fit.set_ylabel('Wavelength')
ax_fit.get_xaxis().set_ticks([]) # Suppress labeling
# Stats
wave_fit = arutils.func_val(fit['fitc'], fit['xfit'], 'legendre',
minv=fit['fmin'], maxv=fit['fmax'])
rms = np.sqrt(np.sum((fit['yfit']-wave_fit)**2)/len(fit['xfit'])) # Ang
dwv_pix = np.median(np.abs(wave-np.roll(wave,1)))
ax_fit.text(0.1*len(arc_spec), 0.90*ymin+(ymax-ymin),
r'$\Delta\lambda$={:.3f}$\AA$ (per pix)'.format(dwv_pix), size='small')
ax_fit.text(0.1*len(arc_spec), 0.80*ymin+(ymax-ymin),
'RMS={:.3f} (pixels)'.format(rms/dwv_pix), size='small')
# Arc Residuals
ax_res = plt.subplot(gs[1,1])
res = fit['yfit']-wave_fit
ax_res.scatter(fit['xfit']*fit['xnorm'], res/dwv_pix, marker='x')
ax_res.plot([xmin,xmax], [0.,0], 'k--')
ax_res.set_xlim(xmin, xmax)
ax_res.set_xlabel('Pixel')
ax_res.set_ylabel('Residuals (Pix)')

# Finish
plt.tight_layout(pad=0.2, h_pad=0.0, w_pad=0.0)
plt.savefig(outfile, dpi=800)
plt.close()

plt.rcdefaults()

return



53 changes: 10 additions & 43 deletions pypit/ararclines.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,18 @@
from astropy.table import Table, Column, vstack
import glob, copy
import yaml
from pkg_resources import resource_filename

from pypit import armsgs
from arclines.io import load_line_list

#from pypit import armsgs
from pypit import msgs
from pypit import arparse as settings

from pypit import ardebug as debugger

# Logging
msgs = armsgs.get_logger()
#msgs = armsgs.get_logger()


def parse_nist(slf,ion):
Expand All @@ -23,47 +27,10 @@ def parse_nist(slf,ion):
ion : str
Name of ion
"""
# Root (for development only)
if slf is None:
from pypit import arutils as arut
msgs.warn("Using arutils.dummy_self. Better know what you are doing.")
slf = arut.dummy_self()
root = settings.argflag['run']['pypitdir']
# Find file
srch_file = root + '/data/arc_lines/NIST/'+ion+'_vacuum.ascii'
nist_file = glob.glob(srch_file)
if len(nist_file) == 0:
msgs.error("Cannot find NIST file {:s}".format(srch_file))
elif len(nist_file) != 1:
msgs.error("Multiple NIST files for {:s}".format(srch_file))
# Read
nist_tbl = Table.read(nist_file[0], format='ascii.fixed_width', comment='#')
gdrow = nist_tbl['Observed'] > 0. # Eliminate dummy lines
nist_tbl = nist_tbl[gdrow]
# Now unique values only (no duplicates)
uniq, indices = np.unique(nist_tbl['Observed'],return_index=True)
nist_tbl = nist_tbl[indices]
# Deal with Rel
agdrel = []
for row in nist_tbl:
try:
gdrel = int(row['Rel.'])
except:
try:
gdrel = int(row['Rel.'][:-1])
except:
gdrel = 0
agdrel.append(gdrel)
agdrel = np.array(agdrel)
# Remove and add
nist_tbl.remove_column('Rel.')
nist_tbl.remove_column('Ritz')
nist_tbl.add_column(Column(agdrel,name='RelInt'))
nist_tbl.remove_column('Acc.')
nist_tbl.remove_column('Type')
#nist_tbl.add_column(Column([ion]*len(nist_tbl), name='Ion', dtype='S5'))
nist_tbl.add_column(Column([ion]*len(nist_tbl), name='Ion', dtype='U5'))
nist_tbl.rename_column('Observed','wave')
nist_path = resource_filename('arclines', 'data/NIST/')
line_file = nist_path+'{:s}_vacuum.ascii'.format(ion)
nist_tbl = load_line_list(line_file, NIST=True)

# Return
return nist_tbl

Expand Down
18 changes: 18 additions & 0 deletions pypit/archeck.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,23 @@

from __future__ import absolute_import, division, print_function

import pkg_resources

requirements_file = pkg_resources.resource_filename('pypit', 'requirements.txt')
install_requires = [line.strip().replace('==', '>=') for line in open(requirements_file)
if not line.strip().startswith('#') and line.strip() != '']
for requirement in install_requires:
pkg, version = requirement.split('>=')
try:
pv = pkg_resources.get_distribution(pkg).version
except pkg_resources.DistributionNotFound:
raise ImportError("Package: {:s} not installed!".format(pkg))
else:
if pkg_resources.parse_version(pv) < pkg_resources.parse_version(version):
print("Version of package {:s} = {:s}".format(pkg, pv))
raise ImportError("You need version >= {:s}".format(version))

'''
from distutils.version import LooseVersion

import warnings
Expand Down Expand Up @@ -42,3 +59,4 @@ def version_check():
for dep, ver in minimum_versions.items():
if LooseVersion(globals()[dep].__version__) < LooseVersion(ver):
raise VersionError('Update ' + dep + ' to at least version ' + ver + '!')
'''
Loading