Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update from dev #425

Merged
merged 158 commits into from
Jan 25, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
158 commits
Select commit Hold shift + click to select a range
533425b
FIX: Replace very inefficient discrete _get_trial
KatharineShapcott Dec 30, 2022
8c1db01
FIX: end of slice incremented by 1
KatharineShapcott Dec 30, 2022
f28eead
FIX: return empty array NOT all data
KatharineShapcott Jan 2, 2023
f2c280c
CHG: remove unique from sample
KatharineShapcott Jan 2, 2023
1cd9b03
CHG: new _trialslice property for DiscreteData
KatharineShapcott Jan 4, 2023
321c2d3
CHG: Update DiscreteData to use _trialslice
KatharineShapcott Jan 4, 2023
f6a6cf3
ise logger in SpyWarning
dfsp-spirit Jan 4, 2023
f777295
NEW: set logger name
dfsp-spirit Jan 4, 2023
c7b6162
Merge branch 'dev' into 208-headless-logging
dfsp-spirit Jan 5, 2023
6464c91
FIX: add import
dfsp-spirit Jan 5, 2023
686f517
CHG: disable test using a slice
dfsp-spirit Jan 5, 2023
d8fbb8c
FIX: remove slice test
dfsp-spirit Jan 5, 2023
481a00e
CHG: replace all print calls with logger calls in errors.py
dfsp-spirit Jan 5, 2023
98ca825
FIX: minor, fix typo
dfsp-spirit Jan 5, 2023
857fd83
FIX: prevent teardown method from being called in parallel test
dfsp-spirit Jan 5, 2023
dc183f6
NEW: add logging documentation to dev docs
dfsp-spirit Jan 5, 2023
25d7403
CHG: fix typo
dfsp-spirit Jan 5, 2023
4ce4e1c
CHG: extend logging documenation
dfsp-spirit Jan 5, 2023
ccbff5c
FIX: no data returns empty array
kshapcott Jan 5, 2023
a946403
Merge pull request #411 from esi-neuroscience/dev
tensionhead Jan 5, 2023
b730e92
CHG: revert sample property
tensionhead Jan 5, 2023
40b9348
set default log level
dfsp-spirit Jan 6, 2023
ae8ab31
Merge branch '208-headless-logging' of https://github.com/esi-neurosc…
dfsp-spirit Jan 6, 2023
49a8241
NEW: allow silencing of module import message
dfsp-spirit Jan 6, 2023
8c9cbf2
NEW: better checking of default log level
dfsp-spirit Jan 6, 2023
2f98f24
NEW: add logdir, move temp storage folder
dfsp-spirit Jan 6, 2023
1011bdb
merge dev, resolve minor conflict in test
dfsp-spirit Jan 6, 2023
7172970
FIX: recursively create dir
dfsp-spirit Jan 6, 2023
404006c
DIX: fix makedirs usage
dfsp-spirit Jan 6, 2023
c8063e9
FIX: allow existing dir
dfsp-spirit Jan 6, 2023
a475af7
NEW: provide different loggers for parallel and seq parts of code
dfsp-spirit Jan 6, 2023
b04141c
CHG: also use loglevel for parallel logger
dfsp-spirit Jan 6, 2023
b0c337c
FIX: create logdir unless exists
dfsp-spirit Jan 6, 2023
0b7fb89
NEW: add function to delete all syncopy log files in log dir
dfsp-spirit Jan 6, 2023
b970f3f
CHG: minor, add info on default append mode for logfiles
dfsp-spirit Jan 6, 2023
4d264a1
NEW: add a SPYDebug method
dfsp-spirit Jan 6, 2023
0ed14dc
Testing
kajal5888 Jan 6, 2023
f8096ea
CHG: log hostname for remote logging
dfsp-spirit Jan 6, 2023
6fec1cc
NEW: add parallel logging functions
dfsp-spirit Jan 9, 2023
435f418
NEW: add docstring for parallel logging function
dfsp-spirit Jan 9, 2023
c04512f
NEW: use parallel logger in FOOOF code.
dfsp-spirit Jan 9, 2023
75bb8ec
NEW: add logging func
dfsp-spirit Jan 9, 2023
6e8ae64
CHG: add DEBUG print in specest
dfsp-spirit Jan 9, 2023
d560a1a
FIX: fix setting of log level
dfsp-spirit Jan 9, 2023
dc2d6e0
FIX: fix debug message to use fstring
dfsp-spirit Jan 9, 2023
c682fe1
WIP: Reorganize channel property for SpikeData
tensionhead Jan 9, 2023
ddf439b
NEW: use parallel logger ater init to test it
dfsp-spirit Jan 9, 2023
602566d
CHG: Remove property computation for unit
tensionhead Jan 9, 2023
8d57890
NEW: allow different log levels for local and parallel loggers
dfsp-spirit Jan 9, 2023
89421c3
NEW: use logger in backend func
dfsp-spirit Jan 9, 2023
fda7338
FIX: add tag in SPYInfo
dfsp-spirit Jan 9, 2023
fe63ee2
CHG: Allow original labels for selections
tensionhead Jan 9, 2023
b256df6
CSD estimation implemented as the output using coherence method
kajal5888 Jan 9, 2023
f1c0755
CSD estimation implemented as a method of connectivity, cfg output co…
kajal5888 Jan 10, 2023
2f2e964
NEW: work on logging doc
dfsp-spirit Jan 10, 2023
8774df3
NEW: explain where users can find logdir value
dfsp-spirit Jan 10, 2023
cc00a6d
Merge branch 'dev' into 208-headless-logging
dfsp-spirit Jan 10, 2023
83455e7
CSD keep trials option implemented
kajal5888 Jan 10, 2023
0c72cfe
CHG: Further streamline channel/unit lookup
tensionhead Jan 10, 2023
048db30
FIX: channel property must be array
tensionhead Jan 10, 2023
6427b35
NEW: add more debug log messages in backend funcs
dfsp-spirit Jan 11, 2023
aba3965
NEW: add more debug information
dfsp-spirit Jan 11, 2023
3f5a3ea
NEW: add more debug messages in backend funcs
dfsp-spirit Jan 11, 2023
2c711f8
NEW: add more debug messages in backend funcs
dfsp-spirit Jan 11, 2023
8356bf3
FIX: fix shape output for SpectralData instance
dfsp-spirit Jan 11, 2023
46389d5
CHG: also log local stuff to a logfile, in addition to console
dfsp-spirit Jan 11, 2023
9a2a4f2
NEW: setup logging of uncaught exceptions
dfsp-spirit Jan 11, 2023
77b1852
FIX: coherence test
tensionhead Jan 11, 2023
9a61c46
Update CHANGELOG.md
tensionhead Jan 11, 2023
6a445a9
FIX: Test issue #257
tensionhead Jan 11, 2023
0ae0718
FIX: catch empty data
tensionhead Jan 11, 2023
c4a34a2
NEW: update logging dev docs
dfsp-spirit Jan 11, 2023
e057290
NEW: finish logging docs
dfsp-spirit Jan 11, 2023
bb65e6a
NEW: add logging tests
dfsp-spirit Jan 11, 2023
be64856
NEW: extend logging tests
dfsp-spirit Jan 11, 2023
7879676
CHG: also add timestamp to logfile, not only console
dfsp-spirit Jan 11, 2023
2862b9a
CHG: use OS-independent path
dfsp-spirit Jan 12, 2023
16aa87c
Merge branch '208-headless-logging' of https://github.com/esi-neurosc…
dfsp-spirit Jan 12, 2023
b7c9e66
NEW: add TODO about excep handler
dfsp-spirit Jan 12, 2023
baa865a
test for output data type added
kajal5888 Jan 12, 2023
055889f
Merge branch 'Add_CSD_Connectivity' of github.com:esi-neuroscience/sy…
kajal5888 Jan 12, 2023
33e1338
CSD is not the normalized spectra
kajal5888 Jan 12, 2023
0c1f988
CHG: Use _trialslice for speed in discrete
kshapcott Jan 12, 2023
3e3e713
WIP: New ad selection tests
tensionhead Jan 12, 2023
349478a
WIP: new spectral data selector tests
tensionhead Jan 12, 2023
241226c
WIP: csd selection tests
tensionhead Jan 12, 2023
4fba003
CHG: remove extra exception handler, already in place below
dfsp-spirit Jan 13, 2023
21b6ebd
update of cfg removed
kajal5888 Jan 13, 2023
8970568
Spectral input check done, parallel and config test failing- need help
kajal5888 Jan 13, 2023
8b1ad4e
CHG: adapt logging test
dfsp-spirit Jan 13, 2023
4a05fb2
uncommented tests
kajal5888 Jan 13, 2023
8039a01
Merge branch 'dev' into 208-headless-logging
dfsp-spirit Jan 13, 2023
4ad1e2f
NEW: disable tqdm unless in TTY
dfsp-spirit Jan 13, 2023
296d682
FIX: Preserve trial selection order upon latency selection
tensionhead Jan 13, 2023
dc8ece2
CHG: log exceptions to parallel logger, they may come from parallel code
dfsp-spirit Jan 13, 2023
b2ae72e
CHG: log exceptions to parallel logger, they may come from parallel code
dfsp-spirit Jan 13, 2023
5f07f89
Test checking
kajal5888 Jan 13, 2023
671b76c
WIP: CSD and Spike selection tests
tensionhead Jan 13, 2023
502ed21
NEW: Selectdata tests
tensionhead Jan 13, 2023
dd30d26
FIX: Formatting and co.
tensionhead Jan 13, 2023
2c066a4
NEW: TrialIndexer
tensionhead Jan 16, 2023
29ae020
CHG: Add tests and check for single trial index
tensionhead Jan 16, 2023
e3dbb3e
FIX: Remove wip return statement
tensionhead Jan 16, 2023
c3529e6
FIX: Use samplerate variable
tensionhead Jan 16, 2023
b95e7cd
Merge pull request #422 from esi-neuroscience/418-re-implement-trials
tensionhead Jan 16, 2023
438f513
FIX: Correct samplerate
tensionhead Jan 17, 2023
9b59124
Merge branch 'dev' into 419-rewrite-selectdata-tests
tensionhead Jan 17, 2023
233b79f
Test config added, test for parallel simplified
kajal5888 Jan 17, 2023
ca8f80d
FIX: use samplerate variable for consistency
KatharineShapcott Jan 17, 2023
0dca548
CHG: clarify comment
KatharineShapcott Jan 17, 2023
5816ae2
Merge pull request #421 from esi-neuroscience/419-rewrite-selectdata-…
dfsp-spirit Jan 17, 2023
c9e3948
CHG: resolve conflices with dev, remove unused import
dfsp-spirit Jan 17, 2023
ba57fd5
Merge branch 'dev' into discrete-speedup
kshapcott Jan 17, 2023
cb15f1f
Merge pull request #423 from esi-neuroscience/dev
tensionhead Jan 17, 2023
0ef4343
CHG: Remove list as parent class of TrialIndexer
tensionhead Jan 17, 2023
ff3a3ba
FIX: Arithmetic comparison
tensionhead Jan 17, 2023
47ea688
CHG: Rewrite channel/unit label setting logic
tensionhead Jan 17, 2023
d5abb62
CHG: Enforce integer data type
tensionhead Jan 17, 2023
6aecbf3
CHG: Make unit indices also 0-based
tensionhead Jan 17, 2023
fa89214
CHG: Add init tests and remove redundant selection tests
tensionhead Jan 17, 2023
39991f2
FIX: Use integer type data for discrete data tests
tensionhead Jan 17, 2023
a7d7893
CHG: Increase coverage
tensionhead Jan 17, 2023
ff23719
FIX: Remove incorrect test
KatharineShapcott Jan 18, 2023
e6bfe1f
FIX: Minor renaming
KatharineShapcott Jan 18, 2023
992e177
FIX: missing not
KatharineShapcott Jan 18, 2023
2917162
FIX: Remove old comment
KatharineShapcott Jan 18, 2023
f7664f9
Merge pull request #415 from esi-neuroscience/408-check-out-contiguou…
tensionhead Jan 18, 2023
6d6dce7
FIX: Remove unique from sample
KatharineShapcott Jan 18, 2023
ce5707c
Merge pull request #403 from esi-neuroscience/discrete-speedup
tensionhead Jan 18, 2023
1841430
Merge branch 'dev' into discrete-get-methods
kshapcott Jan 18, 2023
4753f88
Merge branch 'dev' into discrete-get-methods
kshapcott Jan 18, 2023
4ec7eac
Update Changelog
tensionhead Jan 18, 2023
040888e
Merge pull request #424 from esi-neuroscience/discrete-get-methods
tensionhead Jan 18, 2023
bd134e0
NEW: resolve merge condflict with dev
dfsp-spirit Jan 18, 2023
73a5fe1
CHG: move logging setup to function
dfsp-spirit Jan 18, 2023
50e87f1
replay test for configuration added
kajal5888 Jan 19, 2023
99e723f
Merge pull request #416 from esi-neuroscience/Add_CSD_Connectivity
tensionhead Jan 19, 2023
5ddf312
Merge branch 'dev' into 208-headless-logging
dfsp-spirit Jan 19, 2023
d3d8960
CHG: Print log path on package init
tensionhead Jan 20, 2023
65d8313
CHG: minor change to log dir info message
dfsp-spirit Jan 20, 2023
6310382
NEW: support setting both tempfir and logdir via SPYDIR env var
dfsp-spirit Jan 20, 2023
d25fc84
CHG: refactor to reduce code duplication
dfsp-spirit Jan 20, 2023
ad65b9a
CHG: more logging in parallel mode, separate format
dfsp-spirit Jan 20, 2023
cc3aa9e
NEW: add new IMPORTANT log level, set as default for loggers.
dfsp-spirit Jan 20, 2023
137dffe
NEW: add convenience function set_loglevel
dfsp-spirit Jan 20, 2023
a39bfd4
FIX: pass session to log init func
dfsp-spirit Jan 20, 2023
d4adf50
FIX: change expected log level in test, do not err on custom log leve…
dfsp-spirit Jan 21, 2023
3f14e67
FIX: adapt numeric value of new IMPORTANT level
dfsp-spirit Jan 21, 2023
8836bbe
FIX: fix typo
dfsp-spirit Jan 21, 2023
4e7b13b
NEW: add test for par log file
dfsp-spirit Jan 23, 2023
b65c43a
NEW: test parallel logger
dfsp-spirit Jan 23, 2023
b3d82d6
FIX: minor, fix typo in log message in test
dfsp-spirit Jan 23, 2023
059604c
CHG: remove SessionLogger
dfsp-spirit Jan 23, 2023
bab250c
CHG: Update new default log level in docs.
dfsp-spirit Jan 23, 2023
e9701c8
CHG: set log level of logfile locations on startup to DEBUG
dfsp-spirit Jan 23, 2023
822edd0
CHG: Elevate parallel processing log level
tensionhead Jan 23, 2023
16afe42
CHG: Shorten time format, remove milliseconds
tensionhead Jan 23, 2023
fe1d424
Merge pull request #409 from esi-neuroscience/208-headless-logging
tensionhead Jan 23, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,11 @@ All notable changes to this project will be documented in this file.
### NEW

### CHANGED
- major performance improvements for DiscreteData #403 #418, #424

### Fixed
- fix bug #394 'Copying a spy.StructDict returns a dict'.
- serializable `.cfg` #392

## [2022.12]

Expand Down
3 changes: 2 additions & 1 deletion doc/source/developer/developers.rst
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ Syncopy Developer Guide
***********************

The following information is meant for advanced users with an understanding of
class hierarchies that want to extend and/or modify Syncopy's base functionality.
class hierarchies that want to extend and/or modify Syncopy's base functionality.

.. toctree::
:glob:
Expand All @@ -13,4 +13,5 @@ class hierarchies that want to extend and/or modify Syncopy's base functionality
io
tools
compute_kernels
logging
developer_api
75 changes: 75 additions & 0 deletions doc/source/developer/logging.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
.. _syncopy-logging:

Controlling Logging in Syncopy
===============================

Syncopy uses the `Python logging module <https://docs.python.org/3/library/logging.html>`_ for logging. It uses two different loggers:
one for code that runs on the local machine, and another one for logging the parallelelized code that
is run by the remote workers in a high performance computing (HPC) cluster environment.


Log levels
-----------

The default log level is for the Syncopy logger is `'logging.IMPORTANT'` (from now on referred to as `'IMPORTANT'`). This means that you will not see any Syncopy messages below that threshold, i.e., messages printed with log levels `'DEBUG'` and `'INFO'`. To change the log level, you can either use the logging API in your application code as explained below, or set the environment variable `'SPYLOGLEVEL'` to one of the values supported by the logging module, e.g., 'CRITICAL', 'WARNING', 'INFO', or 'DEBUG'. See the `official docs of the logging module <https://docs.python.org/3/library/logging.html#levels>`_ for details on the supported log levels. Note that IMPORTANT is a custom log level with importance 25, i.e., between INFO and WARNING.


Log file location
-----------------

All Syncopy log files are saved in a configurable directory which we refer to as `SPYLOGDIR`. By default, `SPYLOGDIR` is set to the directory `.spy/logs/` in your home directory (accessible as `~/.spy/logs/` under Linux and Mac OS), and it can be adapted by setting the environment variable `SPYLOGDIR` before running your application.

E.g., if your Python script using Syncopy is `~/neuro/paperfig1.py`, you can set the log level and log directory on the command line like this in the Bash shell:

.. code-block:: shell
export SPYLOGDIR=/tmp/spy
export SPYLOGLEVEL=DEBUG
~/neuro/paperfig1.py


Logging code that runs locally
-------------------------------

For all code that is run on the local machine, Syncopy logs to a logger named `'syncopy'` which is handled by both the console and the logfile `'SPYLOGDIR/syncopy.log'`.

To adapt the local logging behaviour of Syncopy, one can configure the logger as explained in the documentation for the logging module, e.g., in your application that uses Syncopy:

.. code-block:: python

import syncopy
import logging
# Get the logger used by syncopy
logger = logging.getLogger('syncopy')

# Change the log level:
logger.setLevel(logging.DEBUG)

# Add another handler that logs to a file:
fh = logging.FileHandler('syncopy_debug_log.log')
logger.addHandler(fh)

logger.info("My app starts now.")
# The rest of your application code goes here.


Logging code that potentially runs remotely
--------------------------------------------

The parallel code that performs the heavy lifting on the Syncopy data (i.e., what we call `compute functions`) will be executed on remote machines when Syncopy is run in an HPC environment. Therefore,
special handling is required for these parts of the code, and we need to log to one log file per remote machine.

Syncopy automatically configures a suitable logger named `syncopy_<host>` on each host, where `<host>` is the hostname. Each of these loggers is attached to the respective logfile `'SPYLOGDIR/syncopy_<host>.log'`, where `<host>` is the hostname, which ensures that logging works properly even if you log into the same directory on all remote machines (e.g., a home directory that is mounted on all machines via a network file system).

Here is how to log with the remote logger:

.. code-block:: python

import syncopy
import logging, platform

# ...
# In some cF or backend function:
par_logger = logging.getLogger("syncopy_" + platform.node())
par_logger.info("Code run on remote machine is being run.")

This is all you need to do. If you want to configure different log levels for the remote logger and the local one, you can configure the environment variable `SPYPARLOGLEVEL` in addition to `SPYLOGLEVEL`.
58 changes: 44 additions & 14 deletions syncopy/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@
import os
import sys
import subprocess
import socket
import getpass
import socket
import numpy as np
from hashlib import blake2b, sha1
from importlib.metadata import version, PackageNotFoundError
Expand Down Expand Up @@ -36,17 +36,23 @@

# --- Greeting ---

def startup_print_once(message):
"""Print message once: do not spam message n times during all n worker imports."""
try:
dd.get_client()
except ValueError:
silence_file = os.path.join(os.path.expanduser("~"), ".spy", "silentstartup")
if os.getenv("SPYSILENTSTARTUP") is None and not os.path.isfile(silence_file):
print(message)


msg = f"""
Syncopy {__version__}

See https://syncopy.org for the online documentation.
For bug reports etc. please send an email to [email protected]
"""
# do not spam via worker imports
try:
dd.get_client()
except ValueError:
print(msg)
startup_print_once(msg)

# Set up sensible printing options for NumPy arrays
np.set_printoptions(suppress=True, precision=4, linewidth=80)
Expand Down Expand Up @@ -90,28 +96,37 @@

# Set package-wide temp directory
csHome = "/cs/home/{}".format(getpass.getuser())
if os.environ.get("SPYDIR"):
spydir = os.path.abspath(os.path.expanduser(os.environ["SPYDIR"]))
if not os.path.exists(spydir):
raise ValueError(f"Environment variable SPYDIR set to non-existent or unreadable directory '{spydir}'. Please unset SPYDIR or create the directory.")
else:
if os.path.exists(csHome): # ESI cluster.
spydir = os.path.join(csHome, ".spy")
else:
spydir = os.path.abspath(os.path.join(os.path.expanduser("~"), ".spy"))

if os.environ.get("SPYTMPDIR"):
__storage__ = os.path.abspath(os.path.expanduser(os.environ["SPYTMPDIR"]))
else:
if os.path.exists(csHome):
__storage__ = os.path.join(csHome, ".spy")
else:
__storage__ = os.path.join(os.path.expanduser("~"), ".spy")
__storage__ = os.path.join(spydir, "tmp_storage")

if not os.path.exists(spydir):
os.makedirs(spydir, exist_ok=True)

# Set upper bound for temp directory size (in GB)
__storagelimit__ = 10

# Establish ID and log-file for current session
__sessionid__ = blake2b(digest_size=2, salt=os.urandom(blake2b.SALT_SIZE)).hexdigest()
__sessionfile__ = os.path.join(__storage__, "session_{}.id".format(__sessionid__))

# Set max. no. of lines for traceback info shown in prompt
__tbcount__ = 5

# Set checksum algorithm to be used
__checksum_algorithm__ = sha1

# Fill up namespace
# Fill namespace
from . import (
shared,
io,
Expand All @@ -126,8 +141,23 @@
from .plotting import *
from .preproc import *

# Register session
__session__ = datatype.base_data.SessionLogger()
from .datatype.util import setup_storage
storage_tmpdir_size_gb, storage_tmpdir_numfiles = setup_storage() # Creates the storage dir if needed and computes size and number of files in there if any.

from .shared.log import setup_logging
__logdir__ = None # Gets set in setup_logging() call below.
setup_logging(spydir=spydir, session=__sessionid__) # Sets __logdir__.
startup_print_once(f"Logging to log directory '{__logdir__}'.\nTemporary storage directory set to '{__storage__}'.\n")

if storage_tmpdir_size_gb > __storagelimit__:
msg = (
"\nSyncopy <core> WARNING: Temporary storage folder {tmpdir:s} "
+ "contains {nfs:d} files taking up a total of {sze:4.2f} GB on disk. \n"
+ "Consider running `spy.cleanup()` to free up disk space."
)
msg_formatted = msg.format(tmpdir=__storage__, nfs=storage_tmpdir_numfiles, sze=storage_tmpdir_size_gb)
startup_print_once(msg_formatted)


# Override default traceback (differentiate b/w Jupyter/iPython and regular Python)
from .shared.errors import SPYExceptionHandler
Expand Down
2 changes: 2 additions & 0 deletions syncopy/datatype/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
from .methods.selectdata import *
from .methods.show import *
from .methods.copy import *
from .util import *

# Populate local __all__ namespace
__all__ = []
Expand All @@ -25,3 +26,4 @@
__all__.extend(methods.selectdata.__all__)
__all__.extend(methods.show.__all__)
__all__.extend(methods.copy.__all__)
__all__.extend(util.__all__)
Loading