Scientific Computing

Lossless convert PNG image stack to PDF

Converting an image to a PDF file with ImageMagick can be as simple as:

magick in.png out.pdf

For single images -page letter can leave big margins, which may not be desirable.

Convert image stack to PDF: one PNG image per page:

magick -page letter -adjoin *.png joined.pdf
-page letter
does not upsize images, so tiny images will be tiny on the page, one image per page.

Print PDF from any Linux program

On Linux, the CUPS PDF program saves printed PDFs to the ~/PDF directory from any program.

apt install cups-pdf

The PDF output directory can be configured by editing the “Out” directory in /etc/cups/cups-pdf.conf

However, note that higher quality PDF can be obtained by using the PDF print options in the specific program, if available.


Related: convert image stack to PDF

Python pkg_resources.VersionConflict

When using Python project scripts, if one gets:

pkg_resources.VersionConflict: (mypkg 1.1.2 (~/mypkg), Requirement.parse(‘mypkg==1.1.0’))

This can come from an old script in Python bin directory, e.g. ~/miniconda3/bin. Check in the directory coming from:

python -c "import sys; print(sys.executable)"

After finding the old scripts, delete them (be sure they’re not something needed).

Example: suppose package “mypkg” previously contained myprog.py and now the project is moving to the more robust entry_points technique like

[project.scripts]
myprog = mypkg.__main__:cli

Fix by deleting ~/miniconda3/bin/myprog.py.

Find files from the command line

One can very rapidly find files with arbitrary criteria on systems with GNU Findutils. This includes Linux, macOS and Windows Subsystem for Linux.

Install Findutuils

Linux normally comes with GNU Findutils already installed. Windows users can do this via Windows Subsystem for Linux. macOS users can install GNU Findutils via Homebrew that makes the command “gfind” in place of “find”.

A wide range of criteria can be used to rapidly find files. If working on a remote filesystem mounted over SSHFS we suggest SSHing into that system and running the find command that–it will be orders of magnitude faster.

Most examples use home directory ~ as a starting point just for convenience. Appending 2>/dev/null to the end of a command removes nuisance messages about file permissions. If piping the find command, put 2>/dev/null before the pipe.

Find files with “report” in the filename, case-insensitive:

find ~ -iname "*report*"

Suppose ~/data is a symbolic link to another directory, either on your computer, a USB hard drive or a server. By default, find will not search this resource unless you “resolve” the symbolic link to a directory by putting a final / like ~/data/:

find ~/data/ -iname "*report*"

See the findutils manual on symbolic links , in particular the -H and -L options.

Python calling Python via subprocess

On Windows, calling Python sys.executable or console scripts run as .exe may fail with

Fatal Python error: _Py_HashRandomization_Init: failed to get random numbers to initialize Python

The issue arises when environment variables are passed in via the env= argument to Python subprocess. In general, one should add or overwrite variables to the OS environment in subprocess calls as follows in this example for using Clang and Flang compilers. os.environ returns a mapping (general form of dict) of environment variables.

import os
import subprocess

# get a Mapping of all the current environment variables
env = os.environ

# set these to use Clang and Flang compilers
myvar = {'CC': "clang", 'CXX': "clang++", 'FC': "flang"}

# %% This is important--add / overwrite environment variables for this subprocess only.
env.update(myvar)

subprocess.check_call(['meson', 'setup'], env=env)

Whenever using Python subprocess environment variables, generally pass in all the existing environment variables, adding or overwriting the specific variables needed. Otherwise, fundamental environment variables will be missing and the subprocess call generally won’t work. By default, when not specified, env=None, which tells subprocess to copy all the environment variables of the shell Python was called from.

Windows setx environment variables PowerShell

In Windows, the setx command allows storing environment variables in the Windows registry on a per-user or system basis. A problem arises when it is desired to remove such variables entirely. Setting a blank value does not work.

Example: assume one previously set the environment variable CC to the Intel C compiler like:

setx CC icx

Now the problem is, you’d like the system to fall back to using whatever default C compiler is on the Windows system. The existing variable is visible in PowerShell via:

Get-ChildItem Env:CC

But trying to remove the variable with PowerShell command

Remove-Item Env:FC

is only effective for this PowerShell session. The old value of CC comes back upon opening a new PowerShell.

To permanently remove the “setx” variable, we must remove it from where it’s stored in the Windows registry. For this example of wanting to delete enviornment variable CC, do from PowerShell:

reg delete "HKCU\Environment" /v CC

Optionally, confirm deletion with PowerShell:

Get-ChildItem Env:CC

Dual display notes LaTeX Beamer presentation

Pympress can present talk slides using Beamer in dual screen. Practice ahead of time with actual laptop.

Install the prereqs:

Install Pympress:

pip install pympress

Show the Beamer presentation in dual screen by running:

pympress talk.pdf

Tap the s key to swap screens.


In LaTeX .tex preamble (top of main .tex file), put this code to make dual-screen PDF work:

\usepackage{pgfpages}
\setbeameroption{show notes on second screen}

Notes

To fix ModuleNotFoundError: No module named 'gi', install missing prereqs:

apt install python3-gi python3-cairo gir1.2-poppler

Be sure using SYSTEM Python, not Anaconda python or other user Python installs. Remove pympress and pympress*distinfo directories from ~/anaconda3/lib/python*/site-packages/pympress* or wherever it might be on $PATH.

Then install pympress with SYSTEM Python:

/usr/bin/pip3 install --user pympress

Matlab / GNU Octave "isinteractive" function

It’s useful to know if the Matlab or GNU Octave GUI is open for a number of use cases, including

  • pause for each group of a large set of plots–only if user is there to look at them, otherwise save to disk and close thereafter.
  • increase (or decrease) verbosity of print statements or if console output is logged, depending on if it batch mode or not.

We don’t use the Matlab batchStartupOptionUsed as it doesn’t detect the -nodesktop case often used for unattended batch processing. Save this code to isinteractive.m for your project.

function isinter = isinteractive()
%% tell if the program is being run interactively or not.

if isoctave
  isinter = isguirunning;
else
  % matlab, this test doesn't work for Octave
  % don't use batchStartupOptionUsed as it neglects the "-nodesktop" case
  isinter = usejava('desktop');
end

end