Skip to content

Commit 9886fc2

Browse files
committed
Drop Reader and Writer base classes.
1 parent fe077ab commit 9886fc2

File tree

6 files changed

+106
-242
lines changed

6 files changed

+106
-242
lines changed

piff/interp.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -174,7 +174,7 @@ def interpolateList(self, stars, logger=None):
174174
return [ self.interpolate(star) for star in stars ]
175175

176176
def write(self, writer, name):
177-
"""Write an Interp via a Writer object.
177+
"""Write an Interp via a writer object.
178178
179179
Note: this only writes the initialization kwargs to the fits extension, not the parameters.
180180
@@ -207,7 +207,7 @@ def _finish_write(self, writer):
207207

208208
@classmethod
209209
def read(cls, reader, name):
210-
"""Read an Interp via a Reader object.
210+
"""Read an Interp via a reader object.
211211
212212
:param reader: A reader object that encapsulates the serialization format.
213213
:param name: Name associated with this interpolator in the serialized output.

piff/outliers.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ def parseKwargs(cls, config_outliers, logger=None):
9191
return kwargs
9292

9393
def write(self, writer, name):
94-
"""Write an Outers via a Writer object.
94+
"""Write an Outers via a writer object.
9595
9696
:param writer: A writer object that encapsulates the serialization format.
9797
:param name: A name to associate with the Ootliers in the serialized output.

piff/psf.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -719,12 +719,12 @@ def write(self, file_name, logger=None):
719719
:param file_name: The name of the file to write to.
720720
:param logger: A logger object for logging debug info. [default: None]
721721
"""
722-
from .writers import Writer
722+
from .writers import FitsWriter
723723

724724
logger = galsim.config.LoggerWrapper(logger)
725725
logger.warning("Writing PSF to file %s",file_name)
726726

727-
with Writer.open(file_name) as w:
727+
with FitsWriter.open(file_name) as w:
728728
self._write(w, 'psf', logger=logger)
729729

730730
def _write(self, writer, name, logger):

piff/readers.py

+56-121
Original file line numberDiff line numberDiff line change
@@ -18,126 +18,15 @@
1818

1919
from contextlib import contextmanager
2020

21-
import os
2221
import fitsio
2322
import galsim
2423
import numpy as np
2524

2625

27-
class Reader:
28-
"""An interface for reading that abstracts the serialization format.
26+
class FitsReader:
27+
"""A reader object that reads from to multiple FITS HDUs.
2928
30-
The `open` static method should be used to obtain the right reader for
31-
a particular file based on its extension, but specific subclasses can be
32-
constructed directly as well.
33-
34-
A `Reader` subclass is always paired with a `Writer` subclass, and the
35-
methods of `Reader` each directly correspond to a method of `Writer`.
36-
37-
All `Reader` and `Writer` methods take a ``name`` argument that is
38-
associated with the low-level data structured being saved. When writing,
39-
an object can chose not to write a subobject at all with a given name, and
40-
then check to see if the corresponding `Reader` method returns `None`, but
41-
a `Reader` cannot be used to see what type of data structure was saved with
42-
a given name; if this can change, the write implementation must store this
43-
explicitly and use it when invoking the `Reader`.
44-
"""
45-
46-
@staticmethod
47-
@contextmanager
48-
def open(file_name):
49-
"""Return a context manager that yields a `Reader` appropriate for the
50-
given filename.
51-
52-
:param filename: Name of the file to open (`str`).
53-
54-
:returns: A context manager that yields a `Reader`.
55-
"""
56-
_, ext = os.path.splitext(file_name)
57-
if ext == ".fits" or ext == ".piff":
58-
with FitsReader._open(file_name) as reader:
59-
yield reader
60-
return
61-
else:
62-
raise NotImplementedError(f"No reader for extension {ext!r}.")
63-
64-
def read_struct(self, name):
65-
"""Load a simple flat dictionary.
66-
67-
:param name: Name used to save this struct in `Writer.write_struct`.
68-
69-
:returns: A `dict` with `str` keys and `int`, `float`, `str`, `bool`,
70-
or `None` values. If nothing was stored with the given
71-
name, `None` is returned.
72-
"""
73-
raise NotImplementedError()
74-
75-
def read_table(self, name, metadata=None):
76-
"""Load a table as a numpy array.
77-
78-
:param name: Name used to save this table in `Writer.write_table`.
79-
:param metadata: If not `None`, a `dict` to be filled with any
80-
metadata associated with the table on write. Key
81-
case may not be preserved!
82-
83-
:returns: A numpy array with a structured dtype, or `None` if no
84-
object with this name was saved.
85-
"""
86-
raise NotImplementedError()
87-
88-
def read_array(self, name, metadata=None):
89-
"""Load a regular a numpy array that does not have a structured dtype.
90-
91-
:param name: Name used to save this array in `Writer.write_array`.
92-
:param metadata: If not `None`, a `dict` to be filled with any
93-
metadata associated with the array on write. Key
94-
case may not be preserved!
95-
96-
:returns: A numpy array, or `None` if no object with this name was saved.
97-
"""
98-
raise NotImplementedError()
99-
100-
def read_wcs_map(self, name, logger):
101-
"""Load a map of WCS objects and an optional pointing coord.
102-
103-
:param name: Name used to save this map in `Writer.write_array`.
104-
:param logger: A logger object for logging debug info.
105-
106-
:returns: A 2-element tuple, where the first entry is a `dict` with
107-
`int` (chipnum) keys and `galsim.BaseWCS` values, and the
108-
second entry is a `galsim.CelestialCoord` object. Both
109-
entries may be `None`, and if the WCS `dict` is `None` the
110-
pointing coord is always `None`.
111-
"""
112-
raise NotImplementedError()
113-
114-
def nested(self, name):
115-
"""Return a context manager that yields a new `Reader` that reads
116-
content written by a similarly nested `Writer`.
117-
118-
:param name: Base name for all objects read with the returned object.
119-
120-
:returns: A context manager that yields a nested reader object.
121-
"""
122-
raise NotImplementedError()
123-
124-
def get_full_name(self, name):
125-
"""Return the full name of a data structure saved with the given name,
126-
combining it with any base names added if this `Reader` was created by
127-
the `nested` method.
128-
"""
129-
raise NotImplementedError()
130-
131-
132-
class FitsReader(Reader):
133-
"""A `Reader` implementation that reads from to multiple FITS HDUs.
134-
135-
This reader is intended to read files written by Piff before the `Reader`
136-
and `Writer` abstractions were added.
137-
138-
`FitsReader.nested` yields a reader that reads from the same file and
139-
prepends all names with its base name to form the EXTNAME, concatenating
140-
them with ``_``.
29+
This reader is intended to read files written by `FitsWriter`.
14130
14231
:param fits: An already-open `fitsio.FITS` object.
14332
:param base_name: Base name to prepend to all object names, or `None`.
@@ -148,7 +37,7 @@ def __init__(self, fits, base_name):
14837

14938
@classmethod
15039
@contextmanager
151-
def _open(cls, file_name):
40+
def open(cls, file_name):
15241
"""Return a context manager that opens the given FITS file and yields
15342
a `FitsReader` object.
15443
@@ -160,7 +49,14 @@ def _open(cls, file_name):
16049
yield cls(f, base_name=None)
16150

16251
def read_struct(self, name):
163-
# Docstring inherited.
52+
"""Load a simple flat dictionary.
53+
54+
:param name: Name used to save this struct in `FitsWriter.write_struct`.
55+
56+
:returns: A `dict` with `str` keys and `int`, `float`, `str`, `bool`,
57+
or `None` values. If nothing was stored with the given
58+
name, `None` is returned.
59+
"""
16460
extname = self.get_full_name(name)
16561
if extname not in self._fits:
16662
return None
@@ -185,11 +81,28 @@ def read_struct(self, name):
18581
return struct
18682

18783
def read_table(self, name, metadata=None):
188-
# Docstring inherited.
84+
"""Load a table as a numpy array.
85+
86+
:param name: Name used to save this table in `FitsWriter.write_table`.
87+
:param metadata: If not `None`, a `dict` to be filled with any
88+
metadata associated with the table on write. Key
89+
case may not be preserved!
90+
91+
:returns: A numpy array with a structured dtype, or `None` if no
92+
object with this name was saved.
93+
"""
18994
return self.read_array(name, metadata)
19095

19196
def read_array(self, name, metadata=None):
192-
# Docstring inherited.
97+
"""Load a regular a numpy array that does not have a structured dtype.
98+
99+
:param name: Name used to save this array in `FitsWriter.write_array`.
100+
:param metadata: If not `None`, a `dict` to be filled with any
101+
metadata associated with the array on write. Key
102+
case may not be preserved!
103+
104+
:returns: A numpy array, or `None` if no object with this name was saved.
105+
"""
193106
extname = self.get_full_name(name)
194107
if extname not in self._fits:
195108
return None
@@ -198,7 +111,17 @@ def read_array(self, name, metadata=None):
198111
return self._fits[extname].read()
199112

200113
def read_wcs_map(self, name, logger):
201-
# Docstring inherited.
114+
"""Load a map of WCS objects and an optional pointing coord.
115+
116+
:param name: Name used to save this map in `FitsWriter.write_wcs_map`.
117+
:param logger: A logger object for logging debug info.
118+
119+
:returns: A 2-element tuple, where the first entry is a `dict` with
120+
`int` (chipnum) keys and `galsim.BaseWCS` values, and the
121+
second entry is a `galsim.CelestialCoord` object. Both
122+
entries may be `None`, and if the WCS `dict` is `None` the
123+
pointing coord is always `None`.
124+
"""
202125
import base64
203126
import pickle
204127

@@ -262,9 +185,21 @@ def read_wcs_map(self, name, logger):
262185

263186
@contextmanager
264187
def nested(self, name):
265-
# Docstring inherited.
188+
"""Return a context manager that yields a new `FitsReader` that reads
189+
content written by a similarly nested `FitsWriter`.
190+
191+
:param name: Base name for all objects read with the returned object.
192+
193+
:returns: A context manager that yields a nested reader object.
194+
"""
266195
yield FitsReader(self._fits, base_name=self.get_full_name(name))
267196

268197
def get_full_name(self, name: str) -> str:
269-
# Docstring inherited.
198+
"""Return the full name of a data structure saved with the given name,
199+
combining it with any base names added if this `FitsReader` was created
200+
by the `nested` method.
201+
202+
The FITS implementation concatenates with ``_`` as a delimiter, and
203+
uses the full name as the EXTNAME header value.
204+
"""
270205
return name if self._base_name is None else f"{self._base_name}_{name}"

piff/star.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -329,7 +329,7 @@ def makeTarget(cls, x=None, y=None, u=None, v=None, properties={}, wcs=None, sca
329329

330330
@classmethod
331331
def write(cls, stars, writer, name):
332-
"""Write a list of stars to a Writer object.
332+
"""Write a list of stars to a writer object.
333333
334334
:param stars: A list of stars to write
335335
:param writer: A writer object that encapsulates the serialization format.

0 commit comments

Comments
 (0)