"""User utilities==============.. currentmodule:: glassThe following functions/classes provide convenience functionality for usersof the library.Input and Output----------------.. autofunction:: save_cls.. autofunction:: load_cls.. autofunction:: write_catalog"""# noqa: D400from__future__importannotationsfromcontextlibimportcontextmanagerfromtypingimportTYPE_CHECKINGimportnumpyasnpifTYPE_CHECKING:importimportlib.utilimportpathlibfromcollections.abcimportGenerator,Sequencefromnumpy.typingimportNDArrayifimportlib.util.find_spec("fitsio")isnotNone:importfitsio
[docs]defsave_cls(filename:str,cls:Sequence[NDArray[np.float64]|Sequence[float]],)->None:""" Save a list of Cls to file. Uses :func:`numpy.savez` internally. The filename should therefore have a ``.npz`` suffix, or it will be given one. Parameters ---------- filename The name of the file to save to. cls Angular matter power spectra in *GLASS* ordering. """split=np.cumsum([len(cl)forclincls[:-1]])values=np.concatenate(cls)np.savez(filename,values=values,split=split)
[docs]defload_cls(filename:str,)->list[NDArray[np.float64]|Sequence[float]]:""" Load a list of Cls from file. Uses :func:`numpy.load` internally. Parameters ---------- filename The name of the file to load from. Returns ------- The list of Cls. """withnp.load(filename)asnpz:values=npz["values"]split=npz["split"]returnnp.split(values,split)
class_FitsWriter:""" Writer that creates a FITS file. Initialised with the fits object and extension name. """def__init__(self,fits:fitsio.FITS,ext:str|None=None)->None:""" Create a new, uninitialised writer. Parameters ---------- fits The fits object. ext The file extension. """self.fits=fitsself.ext=extdef_append(self,data:NDArray[np.float64]|list[NDArray[np.float64]],names:list[str]|None=None,)->None:""" Write the FITS file. Parameters ---------- data The data to write. names The names of the columns. """ifself.extisNoneorself.extnotinself.fits:self.fits.write_table(data,names=names,extname=self.ext)ifself.extisNone:self.ext=self.fits[-1].get_extnum()else:hdu=self.fits[self.ext]# not using hdu.append here because of incompatibilitieshdu.write(data,names=names,firstrow=hdu.get_nrows())defwrite(self,data:NDArray[np.float64]|None=None,/,**columns:NDArray[np.float64],)->None:""" Write to FITS by calling the internal _append method. Pass either a positional variable (data) or multiple named arguments (**columns) Parameters ---------- data The data to write. columns The columns to write. """# if data is given, write it as it isifdataisnotNone:self._append(data)# if keyword arguments are given, treat them as names and columnsifcolumns:names,values=list(columns.keys()),list(columns.values())self._append(values,names)
[docs]@contextmanagerdefwrite_catalog(filename:pathlib.Path,*,ext:str|None=None,)->Generator[_FitsWriter]:""" Write a catalogue into a FITS file. *ext* is the optional name of the extension. To be used as a context manager:: # create the catalogue writer with write_catalog("catalog.fits") as out: ... # write catalogue columns RA, DEC, E1, E2, WHT with given arrays out.write(RA=lon, DEC=lat, E1=eps1, E2=e2, WHT=w) .. note:: Requires the ``fitsio`` package. Parameters ---------- filename The name of the file to write to. ext The file extension. Yields ------ writer The writer object. """importfitsiowithfitsio.FITS(filename,"rw",clobber=True)asfits:fits.write(None)yield_FitsWriter(fits,ext)