tesliper.writing.writer_base
Interface for witing data to disk.
This module contains writer() factory function that enables to dynamically create
a writer object that’s responsible for saving data in a desired output format.
writer() instantiates a subclass of WriterBase, an Abstract Base Class
also defined here. WriterBase provides an interface for all serial data writers
(objects that export conformers’ data to multiple files) used by tesliper.
WriterBase expects it’s subclasses to provide an extention class attribute,
which is used as an extension of files produced by this particular writer, and also as
an identifier for the output format, used by the writer() factory function.
tesliper is shipped with four such writers: TxtWriter for writting to .txt
files, CsvWriter for writting in CSV format, XlsxWriter for
creating Excel files, and GjfWriter for preparing Gaussian input files.
You may want to export your data to other file formats - in such case you will need to
implement your own writer. To do this, subclass WriterBase, provide it’s
extension as mentioned above, and implement writing methods for data you intend to
support in your writer. The table below lists these methods, along with a brief
description and DataArray-like object, for which the method will be called by
writer’s write() method.
Writer’s Method |
Description |
Associated array |
|---|---|---|
Generic data: any genre that provides one value for each conformer. |
|
|
General information about conformers: energies, imaginary frequencies, stoichiometry. |
||
Detailed information about conformers’ relative energy, including calculated populations |
||
A spectrum - calculated for single conformer or averaged. |
||
Data related to spectral activity, but not convertible to spectra. |
||
Data that may be used to simulate conformers’ spectra. |
||
Spectra for multiple conformers. |
||
Electronic transitions from ground to excited state, contributing to each band. |
||
Geometry (positions of atoms in space) of conformers. |
Note
These methods are not abstract methods, but will still raise a
NotImplementedError if called. This is to let you omit implementation of methods
you don’t need or wouldn’t make sense for the particular format and still provide an
abstract interface. tesliper takes advantage of this in it’s implementation of
GjfWriter, which only implements geometry() method,
because export of, e.g. a calculated spectrum as a Gaussian input would be
pointless.
Writer object decides which of these methods to call based on the type of each
DataArray-like object passed to the write() method. For
some of them, it also passes additional DataArray-like objects, referred to as
extras, e.g. correspomding Bands for spectral data. See documentation for
particular method to learn, which of its parameters are mandatory, which are optional,
and which should expect None as a possible value of extra.
When implementing one of these methods in your writer, you should take care of opening
and closing file files, formatting data you export, and writing to the file. For the
first part you may use one of the helper methods that provide a ready-to-use file
handles: _iter_handles() for writing to many files in batch or
_get_handle() for writing to one file only. Both require a template
that will be used to generate filename for produced files. To learn more about how these
templates are handled by tesliper, see make_name() documentation.
As mentioned before, writer object uses type of the DataArray-like object (or,
more precisely, a name of its class) to decide which method to use for writing to disk.
If you introduce a new subclass of DataArray for handling some genres, you
will need to tell the Writer class, how it should handle these new objects. This is done
by implementing a custom handler method. It’s name should begin with an underscore,
followed by the name of your subclass in lower case, followed by “_handler”. Also, it
should take two parameters: data and extras. First one is a list of instances of
your subclass, second one is a dictionary of special-case genres, both retrieved from
arguments given to write() method (for details on which genres as
treated as special cases, see distribute_data()). Handler is
responsible for calling appropriate writing method with arguments it needs.
Here is an example: let’s assume you have implemented a custom DataArray
subclass for “ldip” and “lrot” genres with some additional functionality, but you’d like
tesliper to treat it as the original ElectronicActivities class for
purposes of writing to disk.
class LengthActivities(ElectronicActivities):
associated_genres = ("ldip", "lrot")
... # custom functionality implemented here
class UpdatedTxtWriter(TxtWriter):
extension = "txt"
def _lengthactivities_handler(self, data, extras):
# written like ``ElectronicActivities``, so just delegate to its handler
self._electronicactivities_handler(data, extras)
If you’d like to treat this new subclass differently, then you should provide a custom writting method for this kind of data:
class UpdatedTxtWriter(TxtWriter):
extension = "txt"
def length_activities(
self,
band: Bands,
data: List[LengthActivities],
name_template: Union[str, Template] = "${conf}.${cat}-${det}.${ext}",
):
# we will use ``_iter_handles`` method for opening/closing files
template_params = {"genre": band.genre, "cat": "activity", "det": "length"}
handles = self._iter_handles(band.filenames, name_template, template_params)
# we will iterate conformer by conformer
values = zip(*[arr.values for arr in data])
for values, handle in zip(values, handles):
... # writting logic
def _lengthactivities_handler(self, data, extras):
self.length_activities(band=extras["wavelengths"], data=data)
In both cases UpdatedTxtWriter will be picked by the writer() instead of the
original TxtWriter, thanks to the automatic registration done by the base
class WriterBase.
Warning
If extension = "txt" line would be omitted in the UpdatedTxtWriter
definition, it would be picked by the writer() for “txt” format anyway,
because extension’s value would be inherited from TxtWriter.
If you want to prevent this, you can provide a falsy value for the extension
class attribute, i.e. an empty string or None.
If your custom writer should still use the same extension as one of the default
writers, provide extension also as an instance-level attribute:
class UpdatedTxtWriter(TxtWriter):
extension = "" # do not register
def __init__(self, destination, mode):
super().__init__(destination, mode)
self.extension = "txt" # use in generated filenames
Functions
|
Factory function that returns concrete implementation of |
Classes
|
Base class for writers that handle export process based on genre of exported data. |
- tesliper.writing.writer_base.writer(fmt: str, destination: Union[str, pathlib.Path], mode: str = 'x', **kwargs) tesliper.writing.writer_base.WriterBase[source]
Factory function that returns concrete implementation of
WriterBasesubclass, most recently defined for export to fmt file format.- Parameters
fmt (str) – File format, to which export will be done.
destination (Union[str, Path]) – Path to file or direcotry, to which export will be done.
mode (str) – Specifies how writing to file should be handled. Should be one of characters: “a” (append to existing file), “x” (only write if file doesn’t exist yet), or “w” (overwrite file if it already exists). Defaults to “x”.
kwargs – Any additional keword arguments will be passed as-is to the constructor of the retrieved
WriterBasesubclass.
- Returns
Initialized
WriterBasesubclass most recently defined for export to fmt file format.- Return type
- Raises
ValueError – If
WriterBasesubclass for export to fmt file format was not defined.
- class tesliper.writing.writer_base.WriterBase(destination: Union[str, pathlib.Path], mode: str = 'x')[source]
Base class for writers that handle export process based on genre of exported data.
Subclasses should provide an
extensionclass-level attribute and writting methods that subclass intend to support (see below). Value ofextensionwill be used to register subclass as a default writer for export to files that this value indicates (“txt”, “csv”, etc.). Not providing value for this attribute results in aTypeErrorexception. If subclass should not be registered, use an empty string as the attribute’s value.WriterBaseprovides awrite()method for writing arbitraryDataArray-like objects to disk. It dispatches those objects to appropriate writing methods, based on their type. Those writing methods are:To learn more about implementing custom writers, see their documentation and
writer_basedocumentation or extend section.- Parameters
destination (str or pathlib.Path) – Directory, to which generated files should be written.
mode (str) – Specifies how writing to file should be handled. Should be one of characters: ‘a’ (append to existing file), ‘x’ (only write if file doesn’t exist yet), or ‘w’ (overwrite file if it already exists).
- energies_order = ['zpe', 'ten', 'ent', 'gib', 'scf']
Default order, in which energy-related data is written to files.
- abstract property extension
Identifier of this writer, indicating the format of files generated, and a default extension of those files used by the
make_name()method. A falsy value, i.e. an empty string orNoneprevents this writer from being registered and used bywriter()factory function.- Returns
Default extension of files generated by this writer and it’s identifier.
- Return type
str
- property mode
Specifies how writing to file should be handled. Should be one of characters: “a”, “x”, or “w”. “a” - append to existing file; “x” - only write if file doesn’t exist yet; “w” - overwrite file if it already exists.
- Raises
ValueError – If given anything other than “a”, “x”, or “w”.
- property destination: pathlib.Path
Directory, to which generated files should be written.
- Raises
FileNotFoundError – If given destination doesn’t exist or is not a directory.
- Type
pathlib.Path
- static distribute_data(data: List) Tuple[Dict[str, List], Dict[str, Any]][source]
Sorts given data by genre category for use by specialized writing methods.
- Returns
distr (dict) – Dictionary with
DataArray-like objects, sorted by their type. Each {key: value} pair is {name of the type in lowercase format: list ofDataArrayobjects of this type}.extras (dict) – Spacial-case genres: extra information used by some writer methods when exporting data. Available {key: value} pairs (if given in data) are:
corrections: dict of {“energy genre”:FloatArray},frequencies:Bands,wavelengths:Bands,excitation:Bands,stoichiometry:InfoArray,charge:IntegerArray,multiplicity:IntegerArray
- make_name(template: Union[str, string.Template], conf: str = '', num: Union[str, int] = '', genre: str = '', cat: str = '', det: str = '', ext: str = '') str[source]
Create filename using given template and given or global values for known identifiers. The identifier should be used in the template as
"${identifier}"where “identifier” is the name of identifier. Available names and their meaning are:${ext}- appropriate file extension${conf}- name of the conformer${num}- number of the file according to internal counter${genre}- genre of exported data${cat}- category of produced output${det}- category-specific detailThe
${ext}identifier is filled with the value of Writersextensionattribute if not explicitly given as parameter to this method’s call. Values for other identifiers should be provided by the caller.- Parameters
template (str or string.Template) – Template that will be used to generate filenames. It should contain only known identifiers, listed above.
conf (str) – value for
${conf}identifier, defaults to empty string.num (str or int) – value for
${str}identifier, defaults to empty string.genre (str) – value for
${genre}identifier, defaults to empty string.cat (str) – value for
${cat}identifier, defaults to empty string.det (str) – value for
${det}identifier, defaults to empty string.ext (str) – value for
${ext}identifier, defaults to empty string.
- Raises
ValueError – If given template or string contains any unexpected identifiers.
Examples
Must be first subclassed and instantiated:
>>> class MyWriter(WriterBase): >>> extension = "foo" >>> wrt = MyWriter("/path/to/some/directory/")
>>> wrt.make_name(template="somefile.${ext}") "somefile.foo" >>> wrt.make_name(template="${conf}.${ext}") ".foo" # conf is empty string by default >>> wrt.make_name(template="${conf}.${ext}", conf="conformer") "conformer.foo" >>> wrt.make_name(template="Unknown_identifier_${bla}.${ext}") Traceback (most recent call last): ValueError: Unexpected identifiers given: bla.
- _get_handle(template: Union[str, string.Template], template_params: dict, open_params: Optional[dict] = None) Iterator[IO][source]
Helper method for creating files. Given additional kwargs will be passed to
Path.open()method. Implemented as context manager for use withwithstatement.- Parameters
template (str or string.Template) – Template that will be used to generate filenames.
template_params (dict) – Dictionary of {identifier: value} for .make_name method.
open_params (dict, optional) – Arguments for
Path.open()used to open file.
- Yields
IO – file handle, will be closed automatically after
withstatement exitsmeta public:
- _iter_handles(filenames: Iterable[str], template: Union[str, string.Template], template_params: dict, open_params: Optional[dict] = None) Iterator[IO][source]
Helper method for iteration over generated files. Given additional kwargs will be passed to
Path.open()method.- Parameters
filenames (list of str) – list of source filenames, used as value for ${conf} placeholder in name_template
template_params (dict) – Dictionary of {identifier: value} for .make_name method.
open_params (dict, optional) – arguments for
Path.open()used to open file.
- Yields
TextIO – file handle, will be closed automatically on next iteration
meta public:
- write(data: List) None[source]
Writes
DataArray-like objects to disk, decides how to write them based on the type of each object. If some types of given objects are not supported by this writer, data of this type is ignored and a warning is emitted.- Parameters
data (List) –
DataArray-like objects that should be written to disk.
- generic(data: List[Union[tesliper.glassware.arrays.DataArray, tesliper.glassware.arrays.IntegerArray, tesliper.glassware.arrays.FloatArray, tesliper.glassware.arrays.BooleanArray, tesliper.glassware.arrays.InfoArray]], name_template: Union[str, string.Template] = '')[source]
Interface for writing generic data: any that provides one value for each conformer. Evoked when handling
DataArray,IntegerArray,FloatArray,BooleanArray, orInfoArray.- Parameters
data – List of objects that provide one value for each conformer.
- Raises
NotImplementedError – Whenever called, this is an interface that should not be used directly.
- overview(energies: Sequence[tesliper.glassware.arrays.Energies], frequencies: Optional[tesliper.glassware.arrays.Bands] = None, stoichiometry: Optional[tesliper.glassware.arrays.InfoArray] = None, name_template: Union[str, string.Template] = '')[source]
Intercafe for generating an overview of known conformers: values of energies, number of imaginary frequencies, and stoichiometry for each conformer. Evoked when handling
Energiesobjects.- Parameters
energies – List of objects representing different energies genres for each conformer. Mandatory in custom implementation.
frequencies –
Bandsof “freq” genre, with list of frequencies for each conformer. Mandatory in custom implementation. May beNonewhen method evoked by handler.stoichiometry – Stoichiometry of each conformer. Mandatory in custom implementation. May be
Nonewhen method evoked by handler.name_template – Template that defines naming scheme for files generated by this method. May be omitted in custom implementation.
- Raises
NotImplementedError – Whenever called, this is an interface that should not be used directly.
- energies(energies: tesliper.glassware.arrays.Energies, corrections: Optional[tesliper.glassware.arrays.FloatArray] = None, name_template: Union[str, string.Template] = '')[source]
Interface for writing energies values, and optionally their corrections. Evoked when handling
Energiesobjects.- Parameters
energies – Conformers’ energies. Mandatory in custom implementation.
corrections – Correction of energies values. Mandatory in custom implementation. May be
Nonewhen method evoked by handler.name_template – Template that defines naming scheme for files generated by this method. May be omitted in custom implementation.
- Raises
NotImplementedError – Whenever called, this is an interface that should not be used directly.
- single_spectrum(spectrum: tesliper.glassware.spectra.SingleSpectrum, name_template: Union[str, string.Template] = '')[source]
Interface for writing a single spectrum to disk: calculated for one conformer or averaged. Evoked when handling
SingleSpectrumobjects.- Parameters
spectrum – Single calculated spectrum. Mandatory in custom implementation.
name_template – Template that defines naming scheme for files generated by this method. May be omitted in custom implementation.
- Raises
NotImplementedError – Whenever called, this is an interface that should not be used directly.
- spectral_data(band: tesliper.glassware.arrays.Bands, data: List[tesliper.glassware.arrays.SpectralData], name_template: Union[str, string.Template] = '')[source]
Interface for writing multiple objects with spectral data that is not a spectral activity (cannot be converted to signal intensity). Evoked when handling one of the:
VibrationalData,ElectronicData,ScatteringDataobjects.- Parameters
band – Band at which transitions occur for each conformer. Mandatory in custom implementation.
data – List of objects representing different spectral data genres (but not spectral activities). Mandatory in custom implementation.
name_template – Template that defines naming scheme for files generated by this method. May be omitted in custom implementation.
- Raises
NotImplementedError – Whenever called, this is an interface that should not be used directly.
- spectral_activities(band: tesliper.glassware.arrays.Bands, data: List[tesliper.glassware.arrays.SpectralActivities], name_template: Union[str, string.Template] = '')[source]
Interface for writing multiple objects with spectral activities (data that may be converted to signal intensity). Evoked when handling one of the:
VibrationalActivities,ElectronicActivities,ScatteringActivitiesobjects.- Parameters
band – Band at which transitions occur for each conformer. Mandatory in custom implementation.
data – List of objects representing different spectral activities genres. Mandatory in custom implementation.
name_template – Template that defines naming scheme for files generated by this method. May be omitted in custom implementation.
- Raises
NotImplementedError – Whenever called, this is an interface that should not be used directly.
- spectra(spectra: tesliper.glassware.spectra.Spectra, name_template: Union[str, string.Template] = '')[source]
Interface for writing a set of spectra of one type calculated for many conformers. Evoked when handling
Spectraobjects.- Parameters
spectra – Spectra of one type calculated for multiple conformers. Mandatory in custom implementation.
name_template – Template that defines naming scheme for files generated by this method. May be omitted in custom implementation.
- Raises
NotImplementedError – Whenever called, this is an interface that should not be used directly.
- transitions(transitions: tesliper.glassware.arrays.Transitions, wavelengths: tesliper.glassware.arrays.Bands, only_highest: bool = True, name_template: Union[str, string.Template] = '')[source]
Interface for writing single object with electronic transitions data. Evoked when handling
Transitionsobjects.- Parameters
transitions – List of objects representing different spectral data genres (but not spectral_activities). Mandatory in custom implementation.
wavelengths – Wavelengths at which transitions occur for each conformer. Mandatory in custom implementation.
only_highest – Boolean flag indicating if all transitions should be written to disk or only these transition that contributes the most for each wavelength/ May be omitted in custom implementation.
name_template – Template that defines naming scheme for files generated by this method. May be omitted in custom implementation.
- Raises
NotImplementedError – Whenever called, this is an interface that should not be used directly.
- geometry(geometry: tesliper.glassware.arrays.Geometry, charge: Optional[Union[tesliper.glassware.arrays.IntegerArray, Sequence[int], int]] = None, multiplicity: Optional[Union[tesliper.glassware.arrays.IntegerArray, Sequence[int], int]] = None, name_template: Union[str, string.Template] = '')[source]
Interface for writing single object with geometry of each conformer. Evoked when handling
Geometryobjects.- Parameters
geometry – Positions of atoms in each conformer. Mandatory in custom implementation.
charge – Value of each structure’s charge. Mandatory in custom implementation.
multiplicity – Value of each structure’s multiplicity. Mandatory in custom implementation.
name_template – Template that defines naming scheme for files generated by this method. May be omitted in custom implementation.
- Raises
NotImplementedError – Whenever called, this is an interface that should not be used directly.