Add configure() function to set up logging, tracebacks printing, plot styling, etc.
Closes #195 (closed).
This adds a
configure method to
finesse that configures the display of log messages depending on whether the user is running Finesse interactively or not. It also allows the user to configure the Finesse plotting, which internally calls
init_plotting(). I see this function as a Finesse equivalent of the Python standard library's
logging.basicConfig() which sets up sensible defaults depending on the environment.
There is also a new context manager to temporarily enable logging to stderr:
from finesse.script import parse from finesse.utilities import logs script = """ laser l1 P=1 space s1 l1.p1 m1.p1 mirror m1 R=0.99 T=0.01 """ print("Parsing without printed log messages...") print(parse(script)) print() with logs(level="info"): print("Parsing with printed log messages...") print(parse(script))
Parsing without printed log messages... Model(λ=1064 nm, untraced, unbuilt) Parsing with printed log messages... finesse.analysis.actions [ INFO]: Scanning parameters  finesse.script.parser [ INFO]: No analysis specified; defaulting to 'noxaxis'. Model(λ=1064 nm, untraced, unbuilt)
(This example is in
Logging configuration is a little complex. If the user is running in an interactive way (IPython, Jupyter, Qtconsole, etc.), then logging is configured by default to log
WARNING messages or higher to
stderr (both are Python logging defaults) without any need to call
configure(). If the user subsequently calls
configure() within an interactive session, e.g. to change to a different log level, then this automatically configured logger gets changed. However, if the user has already configured logging themselves by the time they import
finesse, logging is not configured unless the user calls
configure(log_level=...) to indicate they explicitly want to set it up. Finally, if the user is running non-interactively, e.g. via the normal Python shell or command, then logging is not set up automatically at all and the user must call
configure() or some other means to set up logging.
There is a truth table in the docstring for
configure(), though for some reason I can't get this to display in the API docs because for some reason functions in the root package are not written into the docs (#196 (closed)):
============ ==================== ================= ======================= ================ Interactive? Log level specified? Existing handler? Add Finesse handler Add null handler ============ ==================== ================= ======================= ================ no no no no yes no no yes no no no yes no yes, user defined level no no yes yes yes, user defined level no yes no no yes, default level no yes no yes yes, default level no yes yes no yes, user defined level no yes yes yes yes, user defined level no
There is also a new documentation page showing how to enable logging in various circumstances.
This MR also tweaks the config file hierarchy to no longer copy the "base" configuration to the user's config directory but instead keep it in the source directory. There seems to me to be no point to copy it at all, and this copying was being done on every Finesse run which adds an unnecessary file system operation (and slowdown). Now only a "barebone" user configuration is copied from
src/finesse/usr.ini.dist into the user's home config directory, and the "built-in" config stays in the installation location (which is probably better anyway, as this file should really be managed by the package manager and not be something left around in the user directory).