Is there a code example of magnetometer output for heading in degrees?

I would like to convert the PI-TOP magnetometer output to degrees. When I noticed the PI-TOP SDK uses Vector3D libraries I figured I can use the example Vector 3D heading code, adapt the code, use the appropriate PI-TOP IMU python module and use the example to read the IMU in the Expansion Board. No luck. I’ve also used several other Vector3D examples. Do you have any examples of converting the magnetometer output to heading in degrees ?

Also the pi-top imu utility does not work. I verified IMU functionality with… it works.
For robot navigation I would like know heading in degrees.

Here’s what I have so far. The PiTop is laying flat on the table with display facing up. pretty standard. Is the magnetometer oriented correctly for N S E W heading ? When I spin the Pi-Top to the North I read 100 degrees… and when I spin it in the opposite direction I do not see the results I would expect.
Here’s the code… it’s prety simple. I figured once it works I can code in magnetic deviation. Also calibration does not work with pi-top imu. I get a imu not detected error. But I can read the the imu with the test script.

from dataclasses import fields
from time import sleep
from numpy import arctan2 as atan2
from pitop import IMU
imu = IMU()

while True:
acc = imu.accelerometer
acc_x, acc_y, acc_z = list(getattr(acc, for field in fields(acc))
gyro = imu.gyroscope
gyro_x, gyro_y, gyro_z = list(getattr(gyro, for field in fields(gyro))
mag = imu.magnetometer
mag_x, mag_y, mag_z = list(getattr(mag, for field in fields(mag))

orientation_fusion = imu.orientation
roll, pitch, yaw = list(
    getattr(orientation_fusion, for field in fields(orientation_fusion)

orientation_accelerometer = imu.accelerometer_orientation
roll_acc, pitch_acc, _ = list(
    for field in fields(orientation_accelerometer)
heading = atan2(mag_y, mag_x) * 180 / 3.14159265358979323846    
print(f"heading: {heading}", end ="\r") 
# print(f"mag: {mag_x}, {mag_y}, {mag_z}", end = "\r")