# TRIQS application maxent
# Copyright (C) 2018 Gernot J. Kraberger
# Copyright (C) 2018 Simons Foundation
# Authors: Gernot J. Kraberger and Manuel Zingl
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
import datetime
from warnings import warn
[docs]
class VerbosityFlags(object):
""" Setting verbosity
This describes different verbosity levels for controlling how much
output is generated.
Note that the actual integer values are considered implementation
details and might not be conserved across versions.
VerbosityFlags can be combined using ``|``, e.g. in order to write
out header and timing information, use::
self.verbose = VerbosityFlags.Header | VerbosityFlags.Timing
Additional VerbosityFlags can be set with ``|=``::
self.verbose |= VerbosityFlags.AlphaLoop
and unset with ``&= ~``::
self.verbose &= ~VerbosityFlags.AlphaLoop
Testing for a particular flag can be done with ``&``.
Use this in the :py:class:`.Logtaker` or in the
:py:meth:`.MaxEntLoop.set_verbosity` method.
The following shows a typical output of the code and together with
the VerbosityFlags for the individual lines:
.. code-block:: none
ElementInfo Calculating diagonal elements.
Calling MaxEnt for element 0 0
Header 2018-11-22 16:51:11.012704
MaxEnt run
TRIQS application maxent
...
scaling alpha by a factor 201 (number of data points)
AlphaLoop alpha[0] = 1.00500000e+05, chi2 = 6.90348835e+04, n_iter= 9
SolverDetails 6 Q: 7.031977e+06, max_f: 1.494887e-05, conv: 5.297643e-16
AlphaLoop alpha[1] = 2.69610927e+04, chi2 = 2.69219648e+04, n_iter= 7
...
Timing MaxEnt loop finished in 0:00:00.548325
"""
Quiet = 0
Header = 1
ElementInfo = 2
Timing = 4
AlphaLoop = 8
SolverDetails = 16
Errors = 32
Default = Header | ElementInfo | Timing | AlphaLoop | Errors
[docs]
class Logtaker(object):
""" Handling logging and error messages.
This class allows to log all the information that is written to the
screen to a file as well.
"""
def __init__(self):
self._error_log = []
self.verbose = VerbosityFlags.Default
# which verbosity messages should be printed in one line
self.one_line = VerbosityFlags.SolverDetails
self.logfile = None
# the verbose level of the logfile; if None, use self.verbose
self.logfile_verbose = None
# the last line ending written
self.end = '\n'
self._welcome_message_printed = False
[docs]
def error_message(self, msg, *args, **kwargs):
""" report error and keep track of the error message
Parameters
==========
msg : str
the error message
"""
self._error_log += [msg.format(*args, **kwargs)]
self.message(VerbosityFlags.Errors, 'ERROR: ' + msg, *args, **kwargs)
[docs]
def log_time(self, message_verbosity=VerbosityFlags.Header):
""" print the current time """
self.message(message_verbosity, str(datetime.datetime.now()))
[docs]
def get_error_messages(self):
""" get a list of all error messages raised """
return self._error_log
[docs]
def clear_error_messages(self):
""" clear the list of all error messages raised """
del self._error_log[:]
[docs]
def welcome_message(self, always=False,
message_verbosity=VerbosityFlags.Header):
""" print a welcome message """
if always or not self._welcome_message_printed:
self.log_time(message_verbosity=message_verbosity)
self.message(message_verbosity, "MaxEnt run")
self.message(message_verbosity, "TRIQS application maxent")
self.message(message_verbosity,
"Copyright(C) 2018 Gernot J. Kraberger\n" +
"Copyright(C) 2018 Simons Foundation\n" +
"Authors: Gernot J. Kraberger and Manuel Zingl")
self.message(
message_verbosity,
"This program comes with ABSOLUTELY NO WARRANTY.\n" +
"This is free software, and you are welcome to redistribute" +
"it under certain conditions; see file LICENSE.")
self.message(
message_verbosity,
"Please cite this code and the appropriate original papers (see documentation).\n")
self._welcome_message_printed = True
def verbosity_message(self, msg, iserr=False, *args, **kwargs):
raise NotImplementedError('The function verbosity_message was '
'removed. Please use message instead.')
[docs]
def open_logfile(self, name, append=True):
""" open the log file
Parameters
==========
name : str
the name of the log file
"""
self.logfile = open(name, 'a' if append else 'w')
[docs]
def close_logfile(self):
""" close the log file """
if self.logfile is not None:
self.logfile.close()
self.logfile = None
[docs]
def message(self, message_verbosity, msg, *args, **kwargs):
""" print a message and write it to the log file
Parameters
==========
message_verbosity : :py:class:`.VerbosityFlags`
verbosity flags that must be set in order to write that
message (can be one flag or a ``|`` combination)
msg : str
the message; it can contain {} that are formatted with
``format`` using the ``args`` and ``kwargs``
"""
# check whether all flags given in message_verbosity are set in
# self.verbose
if self.verbose & message_verbosity == message_verbosity:
# if one of the verbosity flags given for this message
# triggers one line behavior
if message_verbosity & self.one_line:
self.end = ''
# go back to the start of the line
print('\r', end=self.end)
elif not self.end == '\n':
# last printed line did not end with newline; print
# newline now
self.end = '\n'
print('', end=self.end)
print(msg.format(*args, **kwargs), end=self.end)
if self.logfile is not None:
logfile_verbose = self.logfile_verbose
if logfile_verbose is None:
logfile_verbose = self.verbose
# there is no one line behavior for the logfile
if logfile_verbose & message_verbosity == message_verbosity:
self.logfile.write(msg.format(*args, **kwargs) + '\n')
[docs]
def logged_message(self, msg, *args, **kwargs):
""" print a message and write it to the log file
.. warning::
The use of ``logged_message`` is deprecated.
Use ``message`` instead.
Parameters
==========
msg : str
the message
"""
warnings.warn(
"logged_message is deprecated. Use message instead.",
DeprecationWarning)
self.message(0, msg, *args, **kwargs)
def solver_verbose_callback(self, *args, **kwargs):
self.message(VerbosityFlags.SolverDetails, *args, **kwargs)