Logging error on Windows

Description of problem

Dear all,

I am trying to run a model from modelDB (link), which conveniently provides a python environment already. After several issues with compilers, I managed to run something, but now I get a new error, which sounds even more mysterious, and in this case, Brian-related. I copy-pasted it below, any idea of what it might be, or how to solve it?
Thank you in advance!

Minimal code to reproduce problem

I simply run the model with the basic user interface provided and default parameters

Full traceback of error (if relevant)

Compiling with cython

--- Logging error ---
Traceback (most recent call last):
  File "C:\Users\nicco\anaconda3\lib\logging\__init__.py", line 1086, in emit
    stream.write(msg + self.terminator)
  File "C:\Users\nicco\anaconda3\lib\encodings\cp1252.py", line 19, in encode
    return codecs.charmap_encode(input,self.errors,encoding_table)[0]
UnicodeEncodeError: 'charmap' codec can't encode character '\u2192' in position 148: character maps to <undefined>
Call stack:
  File "C:\Users\nicco\Desktop\model_hipp_final\user_interface_simple.py", line 476, in <module>
    interface.mainloop()
  File "C:\Users\nicco\anaconda3\lib\tkinter\__init__.py", line 1429, in mainloop
    self.tk.mainloop(n)
  File "C:\Users\nicco\anaconda3\lib\tkinter\__init__.py", line 1892, in __call__
    return self.func(*args)
  File "C:\Users\nicco\Desktop\model_hipp_final\user_interface_simple.py", line 223, in start
    res_1024, all_FR_exc,all_FR_inh=process(runtime, plot_raster,types,all_N,topo,co,co2,A0,A1,dur,f1,duty_cycle,input_type,all_p_intra,all_p_inter,all_gains,all_g_max_i,all_g_max_e,gCAN,save_raster,save_neuron_pos,save_syn_mat,save_all_FR,path,in_file_1,in_file_2,in_file_3,in_fs,tau_Cl,Ek)
  File "C:\Users\nicco\Desktop\model_hipp_final\model_files\single_process.py", line 276, in process
    myNetwork.run(duration=single_runtime,report='text',report_period=300*second)
  File "C:\Users\nicco\anaconda3\lib\site-packages\brian2\core\base.py", line 293, in device_override_decorated_function
    return func(*args, **kwds)
  File "C:\Users\nicco\anaconda3\lib\site-packages\brian2\units\fundamentalunits.py", line 2462, in new_f
    result = f(*args, **kwds)
  File "C:\Users\nicco\anaconda3\lib\site-packages\brian2\core\network.py", line 1007, in run
    self.before_run(namespace)
  File "C:\Users\nicco\anaconda3\lib\site-packages\brian2\core\base.py", line 293, in device_override_decorated_function
    return func(*args, **kwds)
  File "C:\Users\nicco\anaconda3\lib\site-packages\brian2\core\network.py", line 892, in before_run
    obj.before_run(run_namespace)
  File "C:\Users\nicco\anaconda3\lib\site-packages\brian2\groups\group.py", line 1137, in before_run
    self.create_code_objects(run_namespace)
  File "C:\Users\nicco\anaconda3\lib\site-packages\brian2\groups\group.py", line 1130, in create_code_objects
    code_object = self.create_default_code_object(run_namespace)
  File "C:\Users\nicco\anaconda3\lib\site-packages\brian2\groups\group.py", line 1112, in create_default_code_object
    self.codeobj = create_runner_codeobj(group=self.group,
  File "C:\Users\nicco\anaconda3\lib\site-packages\brian2\codegen\codeobject.py", line 435, in create_runner_codeobj
    return device.code_object(owner=group,
  File "C:\Users\nicco\anaconda3\lib\site-packages\brian2\devices\device.py", line 294, in code_object
    scalar_code, vector_code, kwds = generator.translate(abstract_code,
  File "C:\Users\nicco\anaconda3\lib\site-packages\brian2\codegen\generators\base.py", line 260, in translate
    translated = self.translate_statement_sequence(scalar_statements,
  File "C:\Users\nicco\anaconda3\lib\site-packages\brian2\codegen\generators\cython_generator.py", line 205, in translate_statement_sequence
    kwds = self.determine_keywords()
  File "C:\Users\nicco\anaconda3\lib\site-packages\brian2\codegen\generators\cython_generator.py", line 354, in determine_keywords
    user_func = self._add_user_function(varname, var, added)
  File "C:\Users\nicco\anaconda3\lib\site-packages\brian2\codegen\generators\cython_generator.py", line 217, in _add_user_function
    func_code = impl.get_code(self.owner)
  File "C:\Users\nicco\anaconda3\lib\site-packages\brian2\core\functions.py", line 280, in get_code
    return self._code(owner)
  File "C:\Users\nicco\anaconda3\lib\site-packages\brian2\input\timedarray.py", line 87, in cython_impl
    K = _find_K(owner.clock.dt_, dt)
  File "C:\Users\nicco\anaconda3\lib\site-packages\brian2\input\timedarray.py", line 28, in _find_K
    logger.warn(('Group uses a dt of %s while TimedArray uses dt '
  File "C:\Users\nicco\anaconda3\lib\site-packages\brian2\utils\logger.py", line 432, in warn
    self._log('WARNING', msg, name_suffix, once)
  File "C:\Users\nicco\anaconda3\lib\site-packages\brian2\utils\logger.py", line 368, in _log
    the_logger.log(LOG_LEVELS[log_level], msg)
Message: 'Group uses a dt of 100. us while TimedArray uses dt of 0.9765625 ms (ratio: 1/9.765625) → time grids not aligned'
Arguments: ()
WARNING    Group uses a dt of 100. us while TimedArray uses dt of 0.9765625 ms (ratio: 1/9.765625) → time grids not aligned [brian2.input.timedarray]

Hi @NiKnight, hah, a very interesting (but annoying) error :upside_down_face: If you are not interested in the details, directly skip to the workarounds in the end :slight_smile:

In fact, the issue doesn’t have anything to do with TimedArray in itself, it is only triggered by it. The actual problem is in the logging code (I changed the title of your post to reflect this).
Here’s what is happening: in the code that you run, the input is provided via a TimedArray that uses 1024 time bins per second. This triggers a warning, since the simulation time step is dt=0.1ms, i.e. there are 10000 steps every second. This works fine (it’s a warning, not an error), but is a bit odd since due to rounding an “input time step” will sometimes be used for 9, and sometimes for 10 simulation time steps.

Now, the actual error you are getting occurs when Brian tries to write this warning to its log file (by default in a temporary directory, and deleted at the end of the run if no error occurs). The reason for this: the message contains the special character “→”, and the default file encoding on your machine does not handle this character. This won’t happen on Linux or macOS where the default file encoding is UTF-8, which covers a very wide range of characters.
I think this is something that we can easily fix in Brian (by explicitly asking for the file to be written on UTF-8), but until then, I think the following workarounds should work:

Workarounds

Either of the following should work:

  1. Set your Windows default to UTF-8 by chosing “Use Unicode UTF-8 for worldwide language support” as explained here: Using UTF-8 Encoding (CHCP 65001) in Command Prompt / Windows Powershell (Windows 10) - Stack Overflow – note that this can lead to issues in other (mostly old) Windows programs you might use.
  2. If you run the script from a terminal, try running chcp 65001 first to switch the default encoding to UTF-8
  3. In the Python script that you are running, add the following after the from brian2 import * line (it will force Brian’s file log to use utf-8):
BrianLogger.file_handler.encoding = 'utf-8'
BrianLogger.file_handler.stream.close()
BrianLogger.file_handler.stream = None

Hope that works!

In addition to my previous reply: I just noticed that this error should actually not prevent the code from running. The traceback is printed as a --- Logging error ---, but this shouldn’t matter.

Hi @mstimberg !

Thank you for the thorough explanation, it was indeed that, and after having a little difficulty with the first workaround you proposed, I tried the second and it worked!

If you run the script from a terminal, try running chcp 65001 first to switch the default encoding to UTF-8

Also indeed I think there was another error on top of this one, that did not log properly.
Thank you!!