Scientific Computing

Git default remote

Sometimes in Git repositories with substantial amount of branches and history one may get a message on git switch like:

git switch develop1
hint: If you meant to check out a remote tracking branch on, e.g. 'origin',
hint: you can do so by fully qualifying the name with the --track option:
hint:
hint:     git checkout --track origin/<name>
hint:
hint: If you'd like to always have checkouts of an ambiguous <name> prefer
hint: one remote, e.g. the 'origin' remote, consider setting
hint: checkout.defaultRemote=origin in your config.
fatal: 'develop1' matched multiple (2) remote tracking branches

As per that hint, this issue can be resolved by:

git config --global checkout.defaultRemote origin

macOS Terminal shell configuration

macOS Terminal works much like other operating systems, albeit with distinct keybindings from Linux et al.

Under Terminal → Settings → Profile → Shell: “When the shell exists” pick “close if the shell exited cleanly”. This allows Control+D to exit Terminal like on Linux.

To set environment variables across Terminal sessions, put them in file ~/.zshrc. ~/.zshrc even works if one SSH’s into a macOS computer. A typical ~/.zshrc for developers might include:

export PS1="%1~ %# "

This removes the name@machine to declutter the Terminal prompt.

export EDITOR=nano

This sets the default text editor for many programs to nano, which makes operations easy for programs including Git

export CMAKE_GENERATOR=Ninja

This sets the default CMake generator to Ninja.

C++11 nullptr

nullptr is a better defined replacement for NULL in the C++11 standard in header <cstddef> and in the C23 standard in header <stddef.h>. Remember to include these system headers in source code to help compatibility across compilers–especially modern ones as internal includes are refined to have narrower include scope.

Fast updating Matplotlib plots

The basic structure for a rapidly updating animated plot with Matplotlib, without using matplotlib.animation is described below for imshow() and pcolormesh().

NOTE: matplotlib.pyplot.draw() only takes effect on the CURRENT (most recently called) axes. If updating multiple axes, call draw() after each set of axes is modified.

Both examples assume:

from matplotlib.pyplot import figure, draw, pause

# imgs is a N x X x Y image stack

fg = figure()
ax = fg.gca()

If the pause() statement time is too small, Matplotlib may not update the plot at all. Consider your display may not be able to update faster than about pause(0.01).

More examples with speed comparison showing that imshow is faster than pcolormesh generally.

imshow:

h = ax.imshow(imgs[0])  # set initial display dimensions

for img in imgs:
    h.set_data(img)
    draw(), pause(1e-3)

pcolormesh:

h = ax.pcolormesh(imgs[0])  # set initial display dimensions

for img in imgs:
    h.set_array(img.ravel())
    draw(), pause(1e-3)

Animated plots in Matlab / Octave

Intel oneAPI icpx Windows

Intel oneAPI 2023 provides GNU-like and MSVC-like compiler drivers for Windows. This is a good thing, but CMake had assumptions that only C++ compiler driver icpx OR icx would be present. CMake 3.25.2 fixed oneAPI 2023 compiler detection on Windows. Long term, GNU-like support for Windows may also come. Until you update CMake, you can workaround this issue of C++ oneAPI compiler detection on Windows by configuring the CMake project like:

cmake -Bbuild -DCMAKE_CXX_COMPILER=icx

VTK .vtu file format

Numerous programs can write data in VTK file formats accessible from VTK-compatible programs such as ParaView. One of these format is “.vtu”. Adaptive Mesh Refinement (AMR) library ForestClaw has its own routines to write VTK data.

The base 2D VTK writing is done in “forestclaw/src/patches/clawpatch/fclaw2d_clawpatch_output_vtk.c”. The function “fclaw2d_vtk_write_header()” writes the XML header for UnstructuredGrid.

Disable Visual Studio debug model window

Visual Studio executables built in Debug mode by default pop up modal debug windows if an unhandled exception occurs. This can be annoying to developers particularly when unit testing a project. On remote systems, modal windows can become a real issue if the modal window is accidentally off-screen. In such cases it is sometimes hard to get the modal window back to the main desktop to be closed.

Adding a few lines of code to the C++ program works around this issue by redirecting the error text to stderr console and not popping up the modal window. _CrtSetReportMode keeps the model window from appearing. _CrtSetReportFile redirects the message text to stderr so that the message can be diagnosed.

This is also relevant to continuous integration systems such as GitHub Actions, which may hang with an unrealized modal dialog otherwise.

#ifdef _MSC_VER
#include <crtdbg.h>
#endif

int main(){
#ifdef _MSC_VER
    _CrtSetReportMode(_CRT_ASSERT, _CRTDBG_MODE_FILE);
    _CrtSetReportFile(_CRT_ASSERT, _CRTDBG_FILE_STDERR);
    _CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_FILE);
    _CrtSetReportFile(_CRT_WARN, _CRTDBG_FILE_STDERR);
    _CrtSetReportMode(_CRT_ERROR, _CRTDBG_MODE_FILE);
    _CrtSetReportFile(_CRT_ERROR, _CRTDBG_FILE_STDERR);
#endif

// rest of program
}

Visual Studio memory leak detection

Visual Studio can detect memory leaks in programs with _CrtDumpMemoryLeaks. This minimal example doesn’t do the printout. Using these checks requires the project is build in Debug mode.

More complete working minimal example that prints the memory diagnostics with Visual Studio. On Linux, Valgrind can be used to detect memory leaks. Numerous other free memory checkers are available and work with CMake CTest frontend.

#ifdef _MSC_VER
#include <crtdbg.h>
#endif

int main(void){
char* c

c = malloc( 100 );
// unfreed memory, a deliberate leak

// near the end of the function to be checked
#ifdef _MSC_VER
  _CrtDumpMemoryLeaks();
#endif

return 0;
}

Matplotlib AVI / MP4 movie

Matplotlib on any platform can use FFmpeg, Avconv or Mencoder to directly write lossy or lossless compressed movies created from sequences of plots.

Instead of creating hundreds of PNGs, or skipping plots and missing details, Matplotlib movies of a large sequence of plots is highly effective for many processes that evolve across time and/or space.

Alternatively, convert a stack of PNGs to AVI. It’s simpler and often faster and more robust to use Matplotlib.animation.

Lossy

Quality: the default auto bitrate makes excessively compressed, blocky movies. Override the default auto-bitrate with the following snippet:

import matplotlib.animation as anim

Writer = anim.writers['ffmpeg']
writer = Writer(fps=15, codec='mpeg4', bitrate=1e6)
#
with writer.saving(fg, fn,100):
    # code to plot/update figure
    writer.grab_frame(facecolor='k')

Lossless

In matplotlib_writeavi.py, just four added lines of code do the AVI writing. First line tells Matplotlib to use FFmpeg. Second line tells Matplotlib to make a lossless FFV1 video at 15 frames/sec. One can optionally use codec='mpeg4', but lossy encoding can wash out details of plots. Third line says to use 100 DPI (smaller DPI–smaller file and movie size).

import matplotlib.animation as anim

#...

Writer = anim.writers['ffmpeg']
writer = Writer(fps=15, codec='ffv1')
# ...
with writer.saving(fg, fn, 100):
# ...
   writer.grab_frame(facecolor='k')

Troubleshooting

For problems playing back the .avi file, try omitting the codec='ffv1' parameter.

Minimum AVI frame rate: less than 3 fps can invoke bugs on VLC. VLC has trouble with slow frame rate video from any source.

macOS terminal SSH locale

The macOS terminal defaults to UTF8. When SSHing into a macOS computer from a non-macOS computer, or any computer with a different locale, there may be problems running programs on the remote where locale is important. For example, a Linux system with “C” locale may cause .zip archive extraction on remote macOS to fail like:

Pathname cannot be converted from UTF-8 to current locale.

Locally on the macOS computer (or using Remote Desktop over SSH), check locale with:

% locale

LANG="en_US.UTF-8"
LC_COLLATE="en_US.UTF-8"
LC_CTYPE="en_US.UTF-8"
LC_MESSAGES="en_US.UTF-8"
LC_MONETARY="en_US.UTF-8"
LC_NUMERIC="en_US.UTF-8"
LC_TIME="en_US.UTF-8"
LC_ALL=

while from Windows or Linux may result in:

% locale

LANG=""
LC_COLLATE="C"
LC_CTYPE="C"
LC_MESSAGES="C"
LC_MONETARY="C"
LC_NUMERIC="C"
LC_TIME="C"
LC_ALL=

Fix

We resolved this issue by creating on the remote macOS computer a file “locale.sh” containing:

export LANG="en_US.UTF-8"
export LC_COLLATE="en_US.UTF-8"
export LC_CTYPE="en_US.UTF-8"
export LC_MESSAGES="en_US.UTF-8"
export LC_MONETARY="en_US.UTF-8"
export LC_NUMERIC="en_US.UTF-8"
export LC_TIME="en_US.UTF-8"

then run one time when needed:

source ~/locale.sh

This fixed an issue we had with CMake not extracting a .zip file for ExternalProject URL with the error noted at the top of this page.

Another workaround as noted above is to use Remote Desktop over SSH.