Skip to content

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

 
 

Latest commit

 

History

8 Commits

Folders and files

Repository files navigation

b3d_tools

The goal of this project is to provide tools to read, write, and visualize three-dimensional electric field data in the B3D format, in both Matlab and Python.

In the current version, a particular implementation of the latest version 4 is supported, Location and time data must be given as variable points. The data must have at least two float channels (ex and ey). Time offset is not supported. Optionally, the second meta string represents a length-two vector that describes the location points as a grid.

Data format description

Overview

This repository has a Python class (B3D in b3d.py) and a MATLAB class (b3d in b3d.m) with the same fields and the same two jobs: read a B3D version 4 file into memory, and write the in-memory data back to a B3D file. The B3D files these classes handle hold a list of latitude/longitude points, a list of time points, and the x and y electric-field components (Ex, Ey) at every point and time. Both classes write the same layout. Only the grid-dimension text differs (Python writes [3, 2]; MATLAB writes the numbers separated by spaces), and each reader accepts the other's form, so files can be passed between MATLAB and Python. Each language has one example script that builds a small field, writes it, reads it back, doubles it and writes it again. Visualization, named in the goal above, is not implemented yet.

How it works

flowchart LR
    A["Existing .b3d file<br/>(version 4)"] --> B["Reader<br/>B3D(fname) in Python<br/>b3d(fname) in MATLAB"]
    N["Default object<br/>B3D() or b3d()<br/>2x2 grid, 3 time points"] --> C
    B --> C["Object in memory<br/>comment, grid_dim, lat, lon,<br/>time, ex, ey"]
    C --> D["Your code edits the fields<br/>(see example.py, example.m)"]
    D --> E["Writer<br/>write_b3d_file(fname)<br/>checks array sizes"]
    E --> F["New .b3d file<br/>(version 4, Ex and Ey only)"]
Loading

The readers keep only the first two float channels (Ex, Ey) and skip any extra float or byte channels. The writers always write exactly two float channels.

Repository layout

Folder What it contains Main contributor (git history) Start here
Root Python and MATLAB B3D classes, and one example script for each language abirchfield (code and README description), Adam Birchfield (README edits on GitHub) example.py or example.m
__pycache__/ One committed compiled file, b3d.cpython-310.pyc. Python writes its own compiled file when it imports b3d.py, so this one is not needed. abirchfield Nothing to open

Root files:

File What it does
b3d.py B3D class. B3D() builds a default object (2x2 grid, 3 time points, zero field). B3D(fname) reads a file with load_b3d_file. write_b3d_file(fname) checks types and sizes, then writes the file. Needs NumPy.
b3d.m b3d MATLAB class (classdef) with the same fields. b3d() builds a matching default object (2x2 grid, 3 time points, zero field, stored as doubles), b3d(fname) reads a file with read_b3d_file, and write_b3d_file(fname) checks sizes, then writes the file.
example.py Builds a 3x2 grid (6 points) with 10 time points (0 to 900), writes example6by10.b3d, reads it back, doubles Ex and Ey, and writes example6by10_doubled.b3d.
example.m The same steps in MATLAB, with the same output file names.

Setup

Python (any platform; the commands below are for Windows):

  1. Install Python 3. The committed .pyc file was built with Python 3.10.
  2. Open a terminal in the repository folder.
  3. python -m venv .venv
  4. .venv\Scripts\activate
  5. pip install -r requirements.txt (see requirements.txt; NumPy is the only third-party package).

There are no hard-coded paths to edit. The example script writes its output files into the current folder.

MATLAB:

  1. Install MATLAB. No toolboxes are needed. The code uses double-quoted strings, so releases before R2017a cannot run it. The repository does not name a tested release.
  2. In MATLAB, cd to the repository folder, or add it to the path from elsewhere with addpath("<path to b3d_tools>").

Running

Python, from the repository folder with the virtual environment active:

python example.py

It prints Done! and writes example6by10.b3d and example6by10_doubled.b3d in the current folder.

To use the class in your own script, put b3d.py next to the script (or add this folder to sys.path):

from b3d import B3D

b = B3D("input.b3d")            # read
b.ex *= 2                       # edit (the arrays stay float32)
b.write_b3d_file("output.b3d")  # write

MATLAB, from the repository folder in the Command Window:

example

or from a terminal in the repository folder (MATLAB R2019a or later):

matlab -batch "example"

The MATLAB example writes the same two file names as the Python example, so running one overwrites the other's output. To use the class in your own code:

b = b3d("input.b3d");
b.ex = 2*b.ex;
b.write_b3d_file("output.b3d");

Inputs and outputs

  • Input files: B3D version 4 (file code 34280) with location format 1 (a list of points), a time step of 0 (a list of time points), and at least two float channels. The first two float channels are read as Ex and Ey; extra float and byte channels are skipped. The first metastring becomes comment, and the second, if present, becomes grid_dim. A wrong file code, other versions, other location formats, fixed time steps, or fewer than two float channels raise an error.
  • Output files: B3D version 4 with two metastrings (comment and grid_dim), two float channels (Ex, Ey), no byte channels, location format 1 with the third location value set to 0, time offset 0, and time step 0. time_0 and time_units are written as stored in the object. The Python reader keeps a file's time offset in time_offset, but the writer always writes 0.
  • Python field types checked by write_b3d_file: lat and lon float64 of length n; time uint32 of length nt; ex and ey float32 of shape (nt, n). Any other type or shape raises an exception.
  • MATLAB field shapes and types: lat and lon n-by-1 column vectors (row vectors make the writer fail); time a vector of length nt; ex and ey nt-by-n. The reader returns doubles. The writer stores the field as float32 and time as uint32. comment must be a string in double quotes: the writer joins it to the other header text with +, so a character vector in single quotes is added as numbers and the write fails or writes a broken header.
  • Python reads a file with exactly two float channels and no byte channels in one step. Files with extra channels are read with a Python loop over every point, which is slower on large files.
  • The format itself is described in the PDF linked above.

Known issues

  • Both write_b3d_file methods open the output file before checking the data. If a check fails, the file is left empty, and an existing file with that name is lost. In MATLAB the file also stays open; run fclose('all') before retrying. The MATLAB read_b3d_file also leaves the file open when it rejects a file.
  • In MATLAB, grid_dim keeps the default [2 2] when a file has no second metastring, and it is not checked against the number of points. The Python reader sets it to [n, 1] in both cases.
  • Two error messages are wrong: b3d.m says "Only version 2 of B3D format is supported" for any version other than 4, and the longitude type check in b3d.py says "Latitude must by np array of doubles".

Related repositories

Repository Copy Compared with b3d.py here
GMD-Extended-Team B3D Import/b3d.py Same code (line endings ignored)
GMD-Extended-Team b3d.py One small change in write_b3d_file (the output name is held in a separate variable); same behavior
GIC-inclusive-state-estimator DC GIC State Estimator/Optimization/b3d.py Same code (line endings ignored)
GIC-Voltage-Stability Melvin Code/htcm2026-03-18 1/htcm/src/htcm/b3d.py Modified: adds debug logging and a bounds check when reading files with extra channels
Web-Scraping-Project Efield_auto/b3d.py Modified: adds an n_station array that is written as the third location value

Contributors

From the git history:

  • Adam Birchfield: 4 commits (the initial commit and README edits, all made on GitHub, 2022-04-15 and 2023-02-20)
  • abirchfield: 2 commits (all the code and the README description: the initial MATLAB and Python tools on 2022-04-15, and support for files with extra channels on 2023-02-20)
  • Jonathan M. Snodgrass: documentation commits only, from 2026-09-28 (the README sections below the marker and requirements.txt); no code changes

b3d.py names Adam Birchfield as its author; the Adam Birchfield and abirchfield entries are both his.

Status

  • First commit: 2022-04-15. Last code commit: 2023-02-20. Later commits (from 2026-09-28) add only documentation: the README sections below the marker and requirements.txt.
  • The classes were written on 2022-04-15. The only later code change (2023-02-20) let both readers accept files with extra float or byte channels. The example scripts have not changed since 2022-04-15.
  • The repository is one small library with no legacy parts. Visualization, mentioned in the goal and marked "(later)" in the b3d.py header, is not implemented.

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages