# Source code for drizzlepac.updatenpol

#!/usr/bin/env python

# $Id: updatenpol.py 8609 2010-01-19 16:22:48Z hack$

"""
updatenpol: Update the header of ACS file(s) with the names of new
NPOLFILE and D2IMFILE reference files for use with the
C version of MultiDrizzle (astrodrizzle).

:Authors: Warren Hack

:License: :doc:LICENSE

:Usage:
This task can be run from the operating system command line with::

updatenpol [options] input [refdir]

:Command-line Options:
input
The specification of the files to be updated, either as a single filename,
an ASN table name, or wild-card specification
of a list of files.
refdir
The name of the directory containing all the new reference files
(*_npl.fits and *_d2i.fits files).
If no directory is given, it will look in jref$ by default. -h Print the help (this text). -l If specified, copy NPOLFILEs and D2IMFILEs to local directory for use with the input files. -i If specified, the program will interactively request the exact names of the NPOLFILE and D2IMFILE reference files to be used for updating the header of each file. The value of 'refdir' will be ignored in interactive mode. .. warning:: It will ask for the names of the NPOLFILE and D2IMFILE for EACH separate INPUT file when the option -i has been specified. :Example: 1. This command will update all the FLT files in the current directory with the new NPOLFILE and D2IMFILE reference files found in the 'myjref' directory as defined in the environment:: updatenpol *flt.fits myjref$

:Compatability with MultiDrizzle:
The new version of MultiDrizzle (AstroDrizzle) and updatewcs
only work with the new NPOLFILE reference file for the DGEO correction
(to replace the use of DGEOFILE).
In fact, AstroDrizzle has been extensively modified to
prompt the user with a very lengthy explanation on whether it should
stop and allow the user to update the header or continue without
applying the DGEO correction under circumstances when the NPOLFILE
keyword can not be found for ACS.

"""
__docformat__ = 'restructuredtext'

# This is specifically NOT intended to match the package-wide version information.
__version__ = '1.1.0'
__version_date__ = '16-Aug-2011'

import os,sys,shutil

from astropy.io import fits
from stsci.tools import fileutil as fu
from stsci.tools import parseinput
from stsci.tools import teal

from stwcs import updatewcs
from . import util

[docs]def update(input,refdir="jref$",local=None,interactive=False,wcsupdate=True): """ Updates headers of files given as input to point to the new reference files NPOLFILE and D2IMFILE required with the new C version of MultiDrizzle. Parameters ----------- input : string or list Name of input file or files acceptable forms: - single filename with or without directory - @-file - association table - python list of filenames - wildcard specification of filenames refdir : string Path to directory containing new reference files, either environment variable or full path. local : boolean Specifies whether or not to copy new reference files to local directory for use with the input files. interactive : boolean Specifies whether or not to interactively ask the user for the exact names of the new reference files instead of automatically searching a directory for them. updatewcs : boolean Specifies whether or not to update the WCS information in this file to use the new reference files. Examples -------- 1. A set of associated images specified by an ASN file can be updated to use the NPOLFILEs and D2IMFILE found in the local directory defined using the myjref$ environment variable under PyRAF using::

>>>import updatenpol
>>>updatenpol.update('j8bt06010_asn.fits', 'myref$') 2. Another use under Python would be to feed it a specific list of files to be updated using:: >>> updatenpol.update(['file1_flt.fits','file2_flt.fits'],'myjref$')

3. Files in another directory can also be processed using::

>>> updatenpol.update('data$*flt.fits','../new/ref/') Notes ----- .. warning:: This program requires access to the jref$ directory in order
to evaluate the DGEOFILE specified in the input image header.
This evaluation allows the program to get the information it
needs to identify the correct NPOLFILE.

The use of this program now requires that a directory be set up with
all the new NPOLFILE and D2IMFILE reference files for ACS (a single
directory for all files for all ACS detectors will be fine, much like
jref).  Currently, all the files generated by the ACS team has initially

/grp/hst/acs/lucas/new-npl/

The one known limitation to how this program works comes from
confusion if more than 1 file could possibly be used as the new
reference file. This would only happen when NPOLFILE reference files
have been checked into CDBS multiple times, and there are several
versions that apply to the same detector/filter combination.  However,
that can be sorted out later if we get into that situation at all.

"""
print('UPDATENPOL Version',__version__+'('+__version_date__+')')
# expand (as needed) the list of input files
files,fcol = parseinput.parseinput(input)

if not interactive:
# expand reference directory name (if necessary) to
# interpret IRAF or environment variable names
rdir = fu.osfn(refdir)
ngeofiles,ngcol = parseinput.parseinput(os.path.join(rdir,'*npl.fits'))
# Find D2IMFILE in refdir for updating input file header as well
d2ifiles,d2col = parseinput.parseinput(os.path.join(rdir,"*d2i.fits"))

# Now, build a matched list of input files and DGEOFILE reference files
# to use for selecting the appropriate new reference file from the
# refdir directory.
for f in files:
print('Updating: ',f)
fdir = os.path.split(f)[0]
# Open each file...
fimg = fits.open(f, mode='update', memmap=False)
fdet = phdr['detector']
dfile = phdr.get('DGEOFILE','')
if dfile in ['N/A','',' ',None]:
npolname = ''
else:
if not interactive:
# search all new NPOLFILEs for one that matches current DGEOFILE config
npol = find_npolfile(ngeofiles,fdet,[phdr['filter1'],phdr['filter2']])
else:
if sys.version_info[0] >= 3:
npol = input("Enter name of NPOLFILE for %s:"%f)
else:
npol = raw_input("Enter name of NPOLFILE for %s:"%f)
if npol == "": npol = None

if npol is None:
errstr =  "No valid NPOLFILE found in "+rdir+" for detector="+fdet+"\n"
errstr += " filters = "+phdr['filter1']+","+phdr['filter2']
raise ValueError(errstr)

npolname = os.path.split(npol)[1]
if local:
npolname = os.path.join(fdir,npolname)
# clobber any previous copies of this reference file
if os.path.exists(npolname): os.remove(npolname)
shutil.copy(npol,npolname)
else:
if '$' in refdir: npolname = refdir+npolname else: npolname = os.path.join(refdir,npolname) phdr.set('NPOLFILE', value=npolname, comment="Non-polynomial corrections in Paper IV LUT", after='DGEOFILE') # Now find correct D2IFILE if not interactive: d2i = find_d2ifile(d2ifiles,fdet) else: if sys.version_info[0] >= 3: d2i = input("Enter name of D2IMFILE for %s:"%f) else: d2i = raw_input("Enter name of D2IMFILE for %s:"%f) if d2i == "": d2i = None if d2i is None: print('=============\nWARNING:') print(" No valid D2IMFILE found in "+rdir+" for detector ="+fdet) print(" D2IMFILE correction will not be applied.") print('=============\n') d2iname = "" else: d2iname = os.path.split(d2i)[1] if local: # Copy D2IMFILE to local data directory alongside input file as well d2iname = os.path.join(fdir,d2iname) # clobber any previous copies of this reference file if os.path.exists(d2iname): os.remove(d2iname) shutil.copy(d2i,d2iname) else: if '$' in refdir:
d2iname = refdir+d2iname
else:
d2iname = os.path.join(refdir,d2iname)

phdr.set('D2IMFILE', value=d2iname,
comment="Column correction table",
after='DGEOFILE')

# Close this input file header and go on to the next
fimg.close()

if wcsupdate:
updatewcs.updatewcs(f)

[docs]def find_d2ifile(flist,detector):
""" Search a list of files for one that matches the detector specified.
"""
d2ifile = None
for f in flist:
fdet = fits.getval(f, 'detector', memmap=False)
if fdet == detector:
d2ifile = f
return d2ifile

[docs]def find_npolfile(flist,detector,filters):
""" Search a list of files for one that matches the configuration
of detector and filters used.
"""
npolfile = None
for f in flist:
fdet = fits.getval(f, 'detector', memmap=False)
if fdet == detector:
filt1 = fits.getval(f, 'filter1', memmap=False)
filt2 = fits.getval(f, 'filter2', memmap=False)
fdate = fits.getval(f, 'date', memmap=False)
if filt1 == 'ANY' or \
(filt1 == filters[0] and filt2 == filters[1]):
npolfile = f
return npolfile

#
#### Interfaces used by TEAL
#
[docs]def run(configobj=None,editpars=False):
""" Teal interface for running this code.
"""

if configobj is None:

update(configobj['input'],configobj['refdir'],
local=configobj['local'],interactive=configobj['interactive'],
wcsupdate=configobj['wcsupdate'])

def main():

import getopt

try:
optlist, args = getopt.getopt(sys.argv[1:], 'hli')
except getopt.error as e:
print(str(e))
print(__doc__)
print("\t", __version__)

# initialize default values
help = 0
local = False
interactive = False

for opt, value in optlist:
if opt == "-h":
help = 1
if opt == "-l":
local = True
if opt == "-i":
interactive = True
if len(args) < 2:
args.append('jref\$')
if (help):
print(__doc__)
print("\t", __version__+'('+__version_date__+')')
else:
update(args[:-1],args[-1],local=local,interactive=interactive)

if __name__ == "__main__":
main()
"""
Copyright (C) 2003 Association of Universities for Research in Astronomy (AURA)

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:

1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.

2. Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the following
disclaimer in the documentation and/or other materials provided
with the distribution.

3. The name of AURA and its representatives may not be used to
endorse or promote products derived from this software without
specific prior written permission.

THIS SOFTWARE IS PROVIDED BY AURA AS IS'' AND ANY EXPRESS OR IMPLIED
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL AURA BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
DAMAGE.
"""

[docs]def help(file=None):
"""
Print out syntax help for running astrodrizzle

Parameters
----------
file : str (Default = None)
If given, write out help to the filename specified by this parameter
Any previously existing file with this name will be deleted before
writing out the help.

"""
helpstr = getHelpAsString(docstring=True, show_ver = True)
if file is None:
print(helpstr)
else:
if os.path.exists(file): os.remove(file)
f = open(file, mode = 'w')
f.write(helpstr)
f.close()

[docs]def getHelpAsString(docstring = False, show_ver = True):
"""
return useful help from a file in the script directory called

"""
install_dir = os.path.dirname(__file__)
htmlfile = os.path.join(install_dir, 'htmlhelp', taskname + '.html')
helpfile = os.path.join(install_dir, taskname + '.help')

if docstring or (not docstring and not os.path.exists(htmlfile)):
if show_ver:
helpString = os.linesep + \