Scientific Computing

List comments/annotations in PDF

Adobe Reader can export and view a list of comments through the Comment tab on the right side. To do this from a command line program (for example to feed AI analysis / training) consider a Python script using the high performance PyMuPDF (fitz) library:

import fitz
import sys

file = sys.argv[1]

doc = fitz.open(file)

for i, page in enumerate(doc, start=1):
    for a in page.annots() or []:
        info: dict = a.info

        print(
            f"page {i}  {a.type[1]}  "
            f"author={info.get('title')!r}  "
            f"text={info.get('content')!r}"
        )

        # for highlights, get the actual selected words:
        if a.type[1] in ("Highlight", "Underline", "StrikeOut", "Squiggly"):
            print("  quoted:", page.get_textbox(a.rect))

Print PDF from any Linux program

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

apt install printer-driver-cups-pdf
# or
dnf install cups-pdf

# then
systemctl restart cups

Verify a PDF printer is visible:

lpstat -p -d

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

Higher quality PDF might be obtained by using the PDF print options in the specific program, if available.

LibreOffice PDF Conversion

Alternatively, LibreOffice can print compatible documents to PDF directly from the command line in headless mode like:

soffice --headless --convert-to pdf file.docx

Libreoffice can be installed like

apt install libreoffice-common

Related: convert image stack to PDF

Fortran module file format

The Fortran standard does not define a specific Fortran module file format. Each compiler vendor has a unique incompatible Fortran module file format. Fortran module files are not portable between different compilers or even different versions of the same compiler.

LLVM Flang

The LLVM Flang .mod files generated are legal Fortran syntax – they are text files. The .mod format gives the version number, which may be seen like:

head -n1 <moduleName>.mod

The output starts like:

!mod$ v1

GNU Fortran (GFortran)

The GFortran header version is defined in module.cc as variable “MOD_VERSION”. GNU Fortran “gfortran” .mod files are GZIP and is not documented

GCC version module file version
15.x 16
8.x - 14.x 15
5.1.0 14
4.9.2 12
4.8.1 10
4.7.1 9

Examine Gfortran .mod file header like:

gunzip -c <moduleName>.mod | head -n1

The output starts like:

GFORTRAN module version ‘15’ created from …

Intel oneAPI (ifx)

Intel oneAPI .mod files are a proprietary binary format. It is possible to determine the version of the .mod file by using od to look at the first 2 bytes of the .mod file.

od -An -N4 -d <moduleName>.mod

The first number is like “13” and is the module format version. This version may change over time as oneAPI internals change. The second number is the update version, which is fixed at “1”.

There is an undocumented “ifx” compiler option -switch:fe_module_dump that outputs the module and submodule data in text format.

NVHPC and AOCC

NVIDIA HPC SDK (NVHPC) and AOCC compilers generate .mod files that are text files. The format for legacy Flang module files is distinct from LLVMFlang Fortran module files.

The .mod file is a text file, beginning with the version number.

head -n1 <moduleName>.mod

The output is like:

V34 :0x24 dummy

Cray Fortran

By default, Cray Fortran stores uppercase DUMMY.mod filenames. This can be made lowercase with the ftn -ef flag. The Cray Fortran .mod format is proprietary, but the version number might be seen like:

head -n2 <moduleName>.mod

Related: Fortran submodule file naming

Homebrew EOL Intel CPU support

At WWDC25 on June 9 2025, Apple announced that macOS 27 would no longer support Intel CPUs.

In August 2025, Homebrew announced under Future macOS Support that by the end of summer 2026, Intel CPU Macs would no longer receive binary “bottles” and would be deprioritized to Tier 3 in general. Homebrew Tier 3 status implications includes:

  • Homebrew may work, but with a poor and unstable experience
  • Migration to a Tier 1 or 2 configuration or to a non-Homebrew tool is strongly recommended

Homebrew is not distributing binary “bottles” for Intel CPU Mac hardware. This means that commands “brew upgrade” or “brew install” may take a long time (hours) as packages are compiled from source - or may even fail.

To temporarily keep an Intel CPU Mac functional with Homebrew, one can try to use older versions of Homebrew formulae that still support Intel CPUs, or compile packages from source manually. For example, GCC 15 can be used to maintain compatibility with Intel CPU Macs.

Fortran compiler max line length options

The Fortran 202x standard raises the individual Fortran source code line limit to 10000 characters. The new limits also include unlimited continuation lines and a maximum statement length of one million characters. These are stated as “hard limits”. As has historically been the case, many compilers continue to allow going beyond the line limit in a line or beyond even ten million characters in a statement. LLVMFlang is explicitly designed without a particular character limit per line.

Fortran standard source code line length limit
202x 10000
90 132
77 72

Compiler differences in default maximum source code line length can lead to portability issues. For example, Linux workstations or Linux HPC may default to a GCC Gfortran older than version 14 that has a default Fortran source code line length maximum of 132 characters, which is too short for say generated source code containing a data path on a networked HPC drive.

It’s important to be cognizant of the maximum Fortran line length across compilers as developer laptops often default to a recent Flang or Gfortran that both have effectively unlimited line length.

The maximum line length we experienced with no options follows, as determined experimentally with our Fortran maximum line length test program.

Git file mode permissions

In certain situations, there can be nuisance Git dirty repo messages like:

old mode 100755
new mode 100644

The root cause of this false dirty Git status is loss of fidelity of the executable file mode bit. This can occur in situations including:

  • Using WSL Git on a native Windows filesystem or vice versa
  • Linux HPC where files are shared between users

Workaround this ambiguous executable filemode bit for each Git client by executing within the Git repository:

git config core.filemode false

Extracting raw images from PDF

Use Poppler Utils to extract the original high-resolution images from the PDF. Poppler Utils are command line tools and part of the Poppler library.

This method generally yields much better quality images than screenshots of the PDF pages. The “pdfimages” command exports raster images, and “pdftocairo” exports vector graphics.

In these examples, “in.pdf” is the original PDF file.

Export raster PDF images

List all PDF images using pdfimages

pdfimages -list in.pdf

Extract PDF images from all pages, dumping all images in mydoc.pdf to the same directory. Filenames start with out-. There might be a lot of images.

pdfimages -all in.pdf out

Extract PDF images from specific pages: example is for page 3 only:

pdfimages -all -f 3 -l 3 in.pdf out
-f
first page to extract
-l
last page to extract

Export vector PDF images

Export vector PDF page(s) to SVG format using pdftocairo. Here we assume page 3 of the PDF has the vector images of interest.

pdftocairo -svg -f 3 -l 3 in.pdf out.svg

Use an SVG editor like Inkscape to isolate the image from the rest of the pages.

Install Poppler Utils

  • Linux: apt install poppler-utils
  • macOS / Linux (Homebrew): brew install poppler
  • Windows: use WSL poppler

Related: extracting a page(s) from PDF

PDF extract or combine pages

The free Poppler library includes command line tools that can easily extract pages from a PDF file, or combine pages from multiple PDF files into one PDF file. To do so with Adobe Acrobat or FoxIt generally requires a paid license, but Poppler is a free open-source library.

Extracting page(s) from a PDF into a series of separate PDF files is done with pdfseparate. For example, extract pages 2 to 4 from “in.pdf” to files “out-2.pdf”, “out-3.pdf” and “out-4.pdf” using Poppler:

pdfseparate -f 2 -l 4 in.pdf out-%d.pdf

Combining multiple PDF files into one PDF file is done with pdfunite. For example, combine “in1.pdf”, “in2.pdf” and “in3.pdf” into “out.pdf” using Poppler:

pdfunite in-1.pdf in-2.pdf in-3.pdf out.pdf

Poppler is installed by:

  • Linux: apt install poppler-utils
  • macOS: brew install poppler
  • Windows: use WSL poppler

Related: extract raw full-quality images from PDF

Live Sports Radio low-band VHF FM Audio

The company Live Sports Radio has been using low-band (channel 2-5) VHF TV channels for no-delay live FM broadcasts within sports areas. They have been issued hundreds of STAs (Special Temporary Authorizations) by the FCC under FRN 0017507716 to operate on these channels, which are normally reserved for television. The broadcasts are intended to be received by fans in stadiums and arenas, providing live commentary and updates during sporting events. They generally use separate video (to tell people how to tune in) and audio (the actual sports broadcast) channels, with the audio being transmitted as analog FM compatible with broadcast receivers capable of tuning.

Wide-band multi-digital decode chips like the NXP TEF6688 cost about $5 in production quantities and radios containing the TEF6686 retail for around $70, covering the 65 - 108 MHz range plus extensive shortwave and mediumwave AM coverage. This type of chip is too expensive for a give-away promotion radio, so less expensive receivers, using chips like the RDA5807 covering 50 MHz to 108 MHz would be used. Off the shelf radios selling in the $10 range cover 64 MHz to 108 MHz, and with slight customization I believe the vendor could obtain $5 radios covering 50 MHz to 108 MHz, which would be ideal for this application.

The ERP of the transmissions is typically STA authorized at 5 watts. They have been specified to use the Trival AD-44/CW-AH2 which is quite inefficient at these frequencies and only rated for 10 watts input power. They should consider using a more efficient transmit antenna.

Qi 2.2 charging performance

Qi 2.2 or Qi2 25W finally makes wireless charging universal for supported phones with Magnetic Power Profile (MPP). For phones / devices having built in MPP magnets - or a case with magnets - the alignment issues are solved, and the 25 watt charging speed is fast enough to remove most need for plug-in charging of phones. The Google Pixel 11, iPhone 17, and similar flagship phones natively support Qi2 25W, which allows true corded-like charging speeds with a robust magnetic interface. Qi 1.x has been widely available for over a decade, and has long been plagued in practical use with problems associated with a need for tight physical alignment, heat, and slow charging speeds. Note that while Qi2 25W devices are generally backward compatible, there are some older Qi 1.x devices including the Pixel Stand 2 that may not charge newer devices due to mechanical alignment issues.

The original 5 watt Qi was OK for overnight charging. USB-PD wired quick charging can yield charging in 30 minutes for 50%. Qi 1.3 Extended Power Profile (EPP) can yield 15 watt charge with appropriate devices and a 30 watt USB-PD power adapter. 15 to 25 watts is close enough to wired USB-PD, useful for top-off charging. Having adequate USB-PD input power (e.g. 30 watt wall power USB-PD adapter) to the Qi wireless charger is vital to meet full power charging specs.

The closer the phone (thinner the case) and better aligned the phone is, the faster and cooler it will charge. If the device is getting too hot, it will backoff the charge rate to maintain appropriate temperature. The thermal insulating effect of the phone case retains extra heat from charging.