Source code for astropy.io.ascii.daophot

"""An extensible ASCII table reader and writer.

daophot.py:
  Classes to read DAOphot table format

:Copyright: Smithsonian Astrophysical Observatory (2011)
:Author: Tom Aldcroft (aldcroft@head.cfa.harvard.edu)
"""

## 
## Redistribution and use in source and binary forms, with or without
## modification, are permitted provided that the following conditions are met:
##     * Redistributions of source code must retain the above copyright
##       notice, this list of conditions and the following disclaimer.
##     * 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.
##     * Neither the name of the Smithsonian Astrophysical Observatory nor the
##       names of its contributors may be used to endorse or promote products
##       derived from this software without specific prior written permission.
## 
## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 <COPYRIGHT HOLDER> 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.

import re
import numpy as np
from . import core
from . import basic
from . import fixedwidth
from ...utils import OrderedDict

[docs]class Daophot(core.BaseReader): """Read a DAOphot file. Example:: #K MERGERAD = INDEF scaleunit %-23.7g #K IRAF = NOAO/IRAFV2.10EXPORT version %-23s #K USER = davis name %-23s #K HOST = tucana computer %-23s # #N ID XCENTER YCENTER MAG MERR MSKY NITER \\ #U ## pixels pixels magnitudes magnitudes counts ## \\ #F %-9d %-10.3f %-10.3f %-12.3f %-14.3f %-15.7g %-6d # #N SHARPNESS CHI PIER PERROR \\ #U ## ## ## perrors \\ #F %-23.3f %-12.3f %-6d %-13s # 14 138.538 256.405 15.461 0.003 34.85955 4 \\ -0.032 0.802 0 No_error The keywords defined in the #K records are available via output table ``meta`` attribute:: data = ascii.read('t/daophot.dat') for keyword in data.meta['keywords']: print keyword['name'], keyword['value'], keyword['units'], keyword['format'] The units and formats are available in the output table columns:: for colname in data.colnames: col = data[colname] print colname, col.units, col.format """ def __init__(self): core.BaseReader.__init__(self) self.header = DaophotHeader() self.inputter = core.ContinuationLinesInputter() self.inputter.no_continue = r'\s*#' self.data.splitter = fixedwidth.FixedWidthSplitter() self.data.start_line = 0 self.data.comment = r'\s*#'
[docs] def read(self, table): out = core.BaseReader.read(self, table) # Read keywords as a table embedded in the header comments if len(self.comment_lines) > 0: names = ('temp1', 'name', 'temp2', 'value', 'units', 'format') reader = core._get_reader(Reader=basic.NoHeader, comment=r'(?!#K)', names=names) headerkeywords = reader.read(self.comment_lines) out.meta['keywords'] = OrderedDict() for headerkeyword in headerkeywords: keyword_dict = dict((x, headerkeyword[x]) for x in ('value', 'units', 'format')) out.meta['keywords'][headerkeyword['name']] = keyword_dict self.cols = self.header.cols return out
[docs] def write(self, table=None): raise NotImplementedError
class DaophotHeader(core.BaseHeader): """Read the header from a file produced by the IRAF DAOphot routine.""" def __init__(self): core.BaseHeader.__init__(self) self.comment = r'\s*#K' def get_cols(self, lines): """Initialize the header Column objects from the table ``lines`` for a DAOphot header. The DAOphot header is specialized so that we just copy the entire BaseHeader get_cols routine and modify as needed. :param lines: list of table lines :returns: list of table Columns """ # Parse a series of column defintion lines like below. There may be several # such blocks in a single file (where continuation characters have already been # stripped). # #N ID XCENTER YCENTER MAG MERR MSKY NITER # #U ## pixels pixels magnitudes magnitudes counts ## # #F %-9d %-10.3f %-10.3f %-12.3f %-14.3f %-15.7g %-6d coldef_lines = ['', '', ''] starts = ('#N ', '#U ', '#F ') col_width = [] col_len_def = re.compile(r'[0-9]+') re_colformat_def = re.compile(r'#F([^#]+)') for line in lines: if not line.startswith('#'): break # End of header lines else: formatmatch = re_colformat_def.search(line) if formatmatch: form = formatmatch.group(1).split() width = ([int(col_len_def.search(s).group()) for s in form]) # original data format might be shorter than 80 characters # and filled with spaces width[-1] = 80 - sum(width[:-1]) col_width.extend(width) for i, start in enumerate(starts): if line.startswith(start): line_stripped = line[2:] coldef_lines[i] = coldef_lines[i] + line_stripped break # At this point colddef_lines has three lines corresponding to column # names, units, and format. Get the column names by splitting the # first line on whitespace. self.names = coldef_lines[0].split() if not self.names: raise core.InconsistentTableError('No column names found in DAOphot header') ends = np.cumsum(col_width) starts = ends - col_width # If there wasn't a #U defined (not sure of DAOphot specification), then # replace the empty line with the right number of ## indicators, which matches # the DAOphot "no unit" tag. for i, coldef_line in enumerate(coldef_lines): if not coldef_line: coldef_lines[i] = '## ' * len(self.names) # Read the three lines as a basic table. reader = core._get_reader(Reader=basic.Basic, comment=None) reader.header.comment = None coldefs = reader.read(coldef_lines) # Create the list of io.ascii column objects self._set_cols_from_names() # Set units and format as needed. for col in self.cols: if coldefs[col.name][0] != '##': col.units = coldefs[col.name][0] if coldefs[col.name][1] != '##': col.format = coldefs[col.name][1] # Set column start and end positions. Also re-index the cols because # the FixedWidthSplitter does NOT return the ignored cols (as is the # case for typical delimiter-based splitters) for i, col in enumerate(self.cols): col.start = starts[col.index] col.end = ends[col.index] col.index = i self.n_data_cols = len(self.cols)

Page Contents