Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file modified docs/.DS_Store
Binary file not shown.
22 changes: 22 additions & 0 deletions docs/source/dev_reference/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,28 @@ Main module for visualization.
:undoc-members:
:show-inheritance:

========================
:mod:`triggering` Module
========================

Main module for triggering lidar scans.

.. automodule:: adam.triggering
:members:
:undoc-members:
:show-inheritance:

========================
:mod:`testing` Module
========================

Main module for testing.

.. automodule:: adam.triggering
:members:
:undoc-members:
:show-inheritance:

==================
:mod:`util` Module
==================
Expand Down
17 changes: 17 additions & 0 deletions docs/source/user_guide/show_me_the_lakebreeze.rst
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,25 @@ multiple radar scans with one inference step. Batch inference will save computat
by loading the model only once and utilizing vectorization to perform the inference on multiple
radar scans at a time.

.. code-block :: python

import adam

# List of radar scans to process
radar_scans = [
('KLOT', '2025-07-15T18:00:00'),
('KLOT', '2025-07-15T19:00:00'),
('KLOT', '2025-07-15T20:00:00'),
]

# Preprocess all radar scans
preprocessed_scans = [adam.io.preprocess_radar_image(station, time) for station, time in radar_scans]

# Perform batch inference
lake_breeze_results = adam.model.infer_lake_breeze_batch(
preprocessed_scans, model_name='lakebreeze_model_fcn_resnet50_no_augmentation')


Analyzing the mask data in custom workflows
===========================================
The :py:meth:`RadarImage` class contains all of the information you need to perform
Expand Down
4 changes: 2 additions & 2 deletions examples/README.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,5 @@ ADAM's Example Gallery
======================

In this example gallery, we show how to use ADAM to:
* Get a laze breeze mask from a NEXRAD scan
* Determine the instrument pointing direction using ADAM
* Get a laze breeze mask from a NEXRAD scan.
* Determine the instrument pointing direction using ADAM.
7 changes: 2 additions & 5 deletions notebooks/lake_breeze_detection_example.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
},
{
"cell_type": "code",
"execution_count": 1,
"execution_count": null,
"id": "04aecfd3",
"metadata": {},
"outputs": [
Expand All @@ -48,13 +48,10 @@
],
"source": [
"import adam\n",
"import pyart\n",
"import numpy as np\n",
"import matplotlib.pyplot as plt\n",
"import cartopy.crs as ccrs\n",
"import cartopy.feature as cfeature\n",
"from scipy.optimize import minimize\n",
"from scipy.ndimage import center_of_mass, label"
"import cartopy.feature as cfeature\n"
]
},
{
Expand Down
1 change: 1 addition & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ dependencies = [
"safetensors",
"cartopy",
"boto3",
"paramiko"
]

dynamic = ["version"]
Expand Down
6 changes: 4 additions & 2 deletions src/adam/__init__.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
"""Top-level package for ATMOS Analogue Digital Twin."""

__author__ = """Robert Jackson, Seongha Park"""
__version__ = '0.3.1'
__author__ = """Robert Jackson, Bhupendra Raut, Seongha Park"""
__version__ = '0.4.0'


from . import io # noqa
from . import model # noqa
from . import vis # noqa
from . import util # noqa
from . import testing # noqa
from . import triggering # noqa


29 changes: 29 additions & 0 deletions src/adam/testing/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
"""
============================
adam.testing (adam.testing)
============================

.. currentmodule:: adam.testing

This module handles testing utilities for ADAM.



.. autosummary::
:toctree: generated/

FakeSSHClient
FakeSFTP
TEST_RHI_FILE
TEST_PPI_FILE
TEST_PPI_TRIGGERED_SCAN
TEST_RHI_TRIGGERED_SCAN
"""
import os

from .fake_lidar import FakeSFTP, FakeSSHClient # noqa

TEST_RHI_FILE = os.path.join(os.path.dirname(__file__), "data/test_scan_rhi.txt")
TEST_PPI_FILE = os.path.join(os.path.dirname(__file__), "data/test_scan_ppi.txt")
TEST_PPI_TRIGGERED_SCAN = os.path.join(os.path.dirname(__file__), "data/test_scan_ppi_lakebreeze_close.txt")
TEST_RHI_TRIGGERED_SCAN = os.path.join(os.path.dirname(__file__), "data/test_scan_rhi_lakebreeze.txt")
15 changes: 15 additions & 0 deletions src/adam/testing/data/test_scan_ppi.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
7
6
20
A.1=30,S.1=1388,P.1=-125000*A.2=30,S.2=1388,P.2=0
W0
A.1=30,S.1=1388,P.1=-250000*A.2=30,S.2=1388,P.2=0
W0
A.1=30,S.1=1388,P.1=-125000*A.2=30,S.2=1388,P.2=-3472
W0
A.1=30,S.1=1388,P.1=-250000*A.2=30,S.2=1388,P.2=-3472
W0
A.1=30,S.1=1388,P.1=-125000*A.2=30,S.2=1388,P.2=-6944
W0
A.1=30,S.1=1388,P.1=-250000*A.2=30,S.2=1388,P.2=-6944
W0
15 changes: 15 additions & 0 deletions src/adam/testing/data/test_scan_ppi_lakebreeze_close.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
7
6
20
A.1=30,S.1=1388,P.1=-279857*A.2=30,S.2=69,P.2=0
W0
A.1=30,S.1=1388,P.1=-321524*A.2=30,S.2=69,P.2=0
W0
A.1=30,S.1=1388,P.1=-279857*A.2=30,S.2=69,P.2=-3472
W0
A.1=30,S.1=1388,P.1=-321524*A.2=30,S.2=69,P.2=-3472
W0
A.1=30,S.1=1388,P.1=-279857*A.2=30,S.2=69,P.2=-6944
W0
A.1=30,S.1=1388,P.1=-321524*A.2=30,S.2=69,P.2=-6944
W0
7 changes: 7 additions & 0 deletions src/adam/testing/data/test_scan_rhi.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
7
2
20
A.1=30,S.1=1388,P.1=-125000*A.2=30,S.2=1388,P.2=0
W0
A.1=30,S.1=1388,P.1=-125000*A.2=30,S.2=1388,P.2=-62500
W0
7 changes: 7 additions & 0 deletions src/adam/testing/data/test_scan_rhi_lakebreeze.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
7
2
20
A.1=30,S.1=1388,P.1=-300691*A.2=30,S.2=69,P.2=0
W0
A.1=30,S.1=1388,P.1=-300691*A.2=30,S.2=69,P.2=-31250
W0
56 changes: 56 additions & 0 deletions src/adam/testing/fake_lidar.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import os
import logging

class FakeSFTP:
"""
A fake SFTP client for testing purposes. It simulates the behavior of an SFTP client by storing files in the current directory.
"""

def __init__(self):
self.wd = os.path.dirname(__file__)
logging.info(f"Working directory for fake SFTP: {self.wd}")
scan_params_path = os.path.join(self.wd, "C:/Lidar/System/Scan parameters/")
dynscan_path = os.path.join(self.wd, "C:/Users/End User/DynScan/")
os.makedirs(scan_params_path, exist_ok=True)
os.makedirs(dynscan_path, exist_ok=True)
self.files = []

def listdir(self, path): return os.listdir(os.path.join(self.wd, path))
def get(self, remote, local):
remote_path = os.path.join(self.wd, remote)
with open(remote_path, "rb") as f:
data = f.read()
with open(local, "wb") as f:
f.write(data)
def put(self, local, remote):
logging.info(f"Putting file {local} to {remote} in fake SFTP at {self.wd}.")
if remote.startswith("/"):
remote = remote[1:]
remote_path = os.path.join(self.wd, remote)
with open(remote_path, "wb") as f:
f.write(open(local, "rb").read())
self.files.append(remote_path)
def close(self):
for file in self.files:
os.remove(file)
logging.info("Removed files from fake SFTP.")
os.removedirs(os.path.join(self.wd, "C:/Lidar/System/Scan parameters/"))
logging.info("Removed scan parameters directory from fake SFTP.")
os.removedirs(os.path.join(self.wd, "C:/Users/End User/DynScan/"))
def __enter__(self): return self
def __exit__(self, exc_type, exc_val, exc_tb): self.close()

class FakeSSHClient:
"""
A fake SSH client for testing purposes. It simulates the behavior of an SSH client by providing a context manager that returns a FakeSFTP instance.
"""

def __init__(self):
self.sftp = FakeSFTP()
def set_missing_host_key_policy(self, policy): pass
def connect(self, ip_addr, username, password): print(f"Connected to {ip_addr} with username {username}")
def open_sftp(self): return self.sftp
def close(self): self.sftp.close()
def __enter__(self): return self
def __exit__(self, exc_type, exc_val, exc_tb): self.close()

18 changes: 18 additions & 0 deletions src/adam/triggering/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
"""
==============================
ADAM Triggering Module
==============================
.. currentmodule:: adam.triggering

This module handles the generation of scan strategies and triggering of the lidar based on radar data.

.. autosummary::

:toctree: generated/

make_scan_file
send_scan
trigger_lidar_ppis_from_mask
trigger_lidar_rhi_from_mask
"""
from .halo_lidar import make_scan_file, send_scan, trigger_lidar_ppis_from_mask, trigger_lidar_rhi_from_mask # noqa
Loading