Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
9b652e9
Init code upgrade
tonganh Nov 14, 2024
b4ffbaf
Refactor test code and init data
Nov 22, 2024
e3786e3
Merge pull request #1 from tonganh/feat/upgrade-tests-data
tonganh Nov 22, 2024
a46c70c
Improving script for run_all_tests
Dec 2, 2024
7ae69cd
Ignore and removing the unnecessary files for testing
Dec 2, 2024
2ebc88f
Merge pull request #2 from tonganh/feat/upgrade-tests-data
tonganh Dec 2, 2024
7d59d6e
Edit extract dir of test files
Dec 2, 2024
4709a67
Add CI testing for the libarry
Dec 2, 2024
2bbf802
Merge branch 'main' into feat/upgrade-tests-data
Dec 2, 2024
75eb952
Adjusting github action file
Dec 2, 2024
f7fbb84
Merge pull request #3 from tonganh/feat/upgrade-tests-data
tonganh Dec 2, 2024
8eb5aac
Update scrip for test and CI
tonganh Dec 2, 2024
01f3441
Update scrip for test and CI
tonganh Dec 2, 2024
96e33b6
Update scrip for test and CI
tonganh Dec 2, 2024
81c6ca3
Adjust to test multiple versions
tonganh Dec 2, 2024
6e35533
Fix bug for lower python version
tonganh Dec 2, 2024
5e72ba6
Fix bug SyntaxError: EOL while scanning string literal
tonganh Dec 2, 2024
ea21273
Initialize the code for multichanel library dataset
Dec 13, 2024
90149cf
Removing unnecessary code
Dec 23, 2024
8bd2b4e
Finalize code for multi channel image - pyphoon2
Jan 8, 2025
9747976
Sync the newest code
Feb 13, 2025
009985b
Sync version
tonganh Mar 10, 2025
33c9c0c
sync
tonganh Mar 10, 2025
e01e93a
save the test
tonganh Mar 11, 2025
faeef1e
Sync ver2
tonganh Mar 11, 2025
842c157
Fix the lamda function for image
tonganh Mar 11, 2025
07abc33
Fast fix for image
tonganh Mar 11, 2025
8e762ab
sync
tonganh Mar 11, 2025
2ac99bd
sync
tonganh Mar 11, 2025
154f47b
Done all - withouut typhoondataset
tonganh Mar 11, 2025
c033872
sync
tonganh Mar 12, 2025
8d04d16
Refactor code for single channel and multiple channels
tonganh Mar 12, 2025
890d984
sync
tonganh Mar 12, 2025
854cb28
Sync the latest code
tonganh Mar 12, 2025
49f68d9
Sync the latest code
tonganh Mar 12, 2025
32aef23
Improving RAM usage and merging sequences
tonganh Aug 19, 2025
805c9d8
comment test code for merging
tonganh Aug 19, 2025
7763232
Merge pull request #4 from tonganh/feat/multi-channel-update
tonganh Aug 19, 2025
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
79 changes: 79 additions & 0 deletions .github/workflows/python-test.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
name: Python package

on: [push]

jobs:
build:
runs-on: ubuntu-latest
strategy:
matrix:
python-version: ['3.8', '3.10', '3.11']

steps:
# 1. Checkout the repository
- uses: actions/checkout@v4

# 2. Cache Conda packages (optional but recommended)
- name: Cache Conda packages
uses: actions/cache@v3
with:
path: ~/.conda/pkgs
key: ${{ runner.os }}-conda-${{ hashFiles('**/environment.yml') }}
restore-keys: |
${{ runner.os }}-conda-

# 3. Set up Miniconda
- name: Set up Miniconda
uses: conda-incubator/setup-miniconda@v3
with:
auto-activate-base: true
activate-environment: ''

# 4. Create and activate Conda environment
- name: Create and activate Conda environment
shell: bash -l {0}
run: |
if [[ "${{ matrix.python-version }}" == pypy* ]]; then
conda create -n test-env pypy=3.10 -y
else
conda create -n test-env python=${{ matrix.python-version }} -y
fi
source activate test-env
pip install --upgrade pip

# 5. Display Python version
- name: Display Python version
shell: bash -l {0}
run: |
source activate test-env
python -c "import sys; print(sys.version)"

# 6. Install the package
- name: Install pyphoon2 library
shell: bash -l {0}
run: |
source activate test-env
pip install .

# 7. Verify installation
- name: Check if pyphoon2 was installed
shell: bash -l {0}
run: |
source activate test-env
pip list | grep pyphoon2

# 8. Verify PyPy installation (optional)
- name: Verify PyPy installation
if: startsWith(matrix.python-version, 'pypy')
shell: bash -l {0}
run: |
source activate test-env
pypy --version

# 9. Run tests
- name: Run tests
shell: bash -l {0}
run: |
source activate test-env
cd tests
# sh run_all_tests.sh
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
# Dataset files
*.tsv
*.h5

*.zip
# Byte-compiled / optimized / DLL files
tests/test_data_files
__pycache__/
*.py[cod]
*$py.class
Expand Down
13 changes: 6 additions & 7 deletions docs/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,18 @@
# -- Project information -----------------------------------------------------
# https://www.sphinx-doc.org/en/master/usage/configuration.html#project-information

import os
import sys
project = 'pyphoon2'
copyright = '2023, Jared Hwang'
author = 'Jared Hwang'
release = '1.0.0'
copyright = '2023, Jared Hwang. 2024, Ngoc Anh Tong'
author = 'Jared Hwang, Ngoc Anh Tong'
release = '2.0.0'


templates_path = ['_templates']
exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store']



# -- Options for HTML output -------------------------------------------------
# https://www.sphinx-doc.org/en/master/usage/configuration.html#options-for-html-output

Expand All @@ -25,8 +26,6 @@


# Path setup
import os
import sys
sys.path.insert(0, os.path.abspath('../'))
sys.path.insert(0, os.path.abspath('../pyphoon2'))

Expand All @@ -38,7 +37,7 @@
'sphinx.ext.autodoc', # Core library for html generation from docstrings
'sphinx.ext.autosummary', # Create neat summary tables
]
autosummary_generate = True
autosummary_generate = True
autodoc_member_order = 'bysource'

autodoc_default_options = {
Expand Down
10 changes: 8 additions & 2 deletions docs/frame_model.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
# autopep8: off
import os
import sys
import os.path
sys.path.insert(0, os.path.abspath(
os.path.join(os.path.dirname(__file__), '..')))
import torch
from torch import nn
from torch import optim
Expand All @@ -10,7 +16,7 @@
from pathlib import Path
from torch.utils.data import DataLoader

from DigitalTyphoonDataloader.DigitalTyphoonDataset import DigitalTyphoonDataset
from pyphoon2.DigitalTyphoonDataset import DigitalTyphoonDataset

def main(args):

Expand Down Expand Up @@ -112,7 +118,7 @@ def transform_func(image_ray):

# Calculate the loss
loss = criterion(predictions, labels)

# backward pass
loss.backward()
# update weights
Expand Down
2 changes: 1 addition & 1 deletion docs/model_example_1.rst
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ The Code
from pathlib import Path
from torch.utils.data import DataLoader

from DigitalTyphoonDataloader.DigitalTyphoonDataset import DigitalTyphoonDataset
from pyphoon2.DigitalTyphoonDataset import DigitalTyphoonDataset import DigitalTyphoonDataset

def main(args):

Expand Down
2 changes: 1 addition & 1 deletion docs/model_example_2.rst
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ The Code
from pathlib import Path
from torch.utils.data import DataLoader

from DigitalTyphoonDataloader.DigitalTyphoonDataset import DigitalTyphoonDataset
from pyphoon2.DigitalTyphoonDataset import DigitalTyphoonDataset import DigitalTyphoonDataset

def main(args):

Expand Down
70 changes: 39 additions & 31 deletions docs/padlabels.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,19 +11,20 @@
from pathlib import Path
from torch.utils.data import DataLoader

from DigitalTyphoonDataloader.DigitalTyphoonDataset import DigitalTyphoonDataset
from pyphoon2.DigitalTyphoonDataset import DigitalTyphoonDataset import DigitalTyphoonDataset


def main(args):

## Prepare the data
# Prepare the data

# Specify the paths to the data
data_path = args.dataroot
images_path = data_path + '/image/' # to the image folder
metadata_path = data_path + '/metadata/' # to the metadata folder
images_path = data_path + '/image/' # to the image folder
metadata_path = data_path + '/metadata/' # to the metadata folder
json_path = data_path + '/metadata.json' # to the metadata json

# Define a filter to pass to the loader.
# Define a filter to pass to the loader.
# Any image that the function returns true will be included
def image_filter(image):
return image.grade() < 7
Expand All @@ -33,17 +34,22 @@ def image_filter(image):
# So, image-by-image transforms (i.e. clipping, downsampling, etc. can/should be done here)
def transform_func(image_ray):
# Clip the pixel values between 150 and 350
image_ray = np.clip(image_ray, standardize_range[0], standardize_range[1])
image_ray = np.clip(
image_ray, standardize_range[0], standardize_range[1])

# Standardize the pixel values between 0 and 1
image_ray = (image_ray - standardize_range[0]) / (standardize_range[1] - standardize_range[0])
image_ray = (
image_ray - standardize_range[0]) / (standardize_range[1] - standardize_range[0])

# Downsample the images to 224, 224
if downsample_size != (512, 512):
image_ray = torch.Tensor(image_ray)
image_ray = torch.reshape(image_ray, [1, 1, image_ray.size()[0], image_ray.size()[1]])
image_ray = nn.functional.interpolate(image_ray, size=downsample_size, mode='bilinear', align_corners=False)
image_ray = torch.reshape(image_ray, [image_ray.size()[2], image_ray.size()[3]])
image_ray = torch.reshape(
image_ray, [1, 1, image_ray.size()[0], image_ray.size()[1]])
image_ray = nn.functional.interpolate(
image_ray, size=downsample_size, mode='bilinear', align_corners=False)
image_ray = torch.reshape(
image_ray, [image_ray.size()[2], image_ray.size()[3]])
image_ray = image_ray.numpy()
return image_ray

Expand All @@ -52,42 +58,42 @@ def transform_func(image_ray):
str(metadata_path),
str(json_path),
'grade', # the labels we'd like to retrieve from the dataset
get_images_by_sequence=True, # indicate we want typhoon sequences returned
filter_func=image_filter, # the filter function defined above
transform_func=transform_func, # the transform function defined above
transform=transforms.Compose([ # pytorch transform to apply to data before returning data
get_images_by_sequence=True, # indicate we want typhoon sequences returned
filter_func=image_filter, # the filter function defined above
transform_func=transform_func, # the transform function defined above
transform=transforms.Compose([ # pytorch transform to apply to data before returning data
PadSequence(505),
]),
verbose=False)


# Split the dataset into a training and test split (80% and 20% respectively)
# split by sequence so all images in one sequence will belong to the same bucket
# split by sequence so all images in one sequence will belong to the same bucket
train_set, test_set = dataset.random_split([0.8, 0.2], split_by='sequence')

# Make Pytorch DataLoaders out of the returned sets. From here, it retains all Pytorch functionality.
trainloader = DataLoader(train_set, batch_size=batch_size, shuffle=True, num_workers=num_workers)
testloader = DataLoader(test_set, batch_size=batch_size, shuffle=False, num_workers=num_workers)

trainloader = DataLoader(
train_set, batch_size=batch_size, shuffle=True, num_workers=num_workers)
testloader = DataLoader(test_set, batch_size=batch_size,
shuffle=False, num_workers=num_workers)

## Prepare the model
# Prepare the model
# Hyperparameters
num_epochs = args.max_epochs
batch_size = 16
learning_rate = 0.001
standardize_range = (150, 350)
downsample_size = (224, 224)

# Create a dummy model that will take input of size (505, 224, 224) (seq length, height, width) and output
# Create a dummy model that will take input of size (505, 224, 224) (seq length, height, width) and output
# a value for each image in the sequence (shape (505))
linear1 = nn.Linear(224, 1)

# Loss and optimizer
criterion = nn.CrossEntropyLoss()
optimizer = torch.optim.SGD(model.parameters(), lr=learning_rate, momentum=0.9)
optimizer = torch.optim.SGD(
model.parameters(), lr=learning_rate, momentum=0.9)


## Train the model
# Train the model
for epoch in np.arange(max_epochs):

batches_per_epoch = len(trainloader)
Expand All @@ -99,11 +105,12 @@ def transform_func(image_ray):

# Data is a tuple, with sequence in data[0] and labels in data[1]
# sequence is shape (16, 505, 224, 224) (batch size, seq len, height, width)
# labels size is (16, 505) as we padded them as well.
# labels size is (16, 505) as we padded them as well.
sequence, labels = data

# cast pixels to float and grade (label) to long
sequence, labels = torch.Tensor(sequence).float(), torch.Tensor(labels).long()
sequence, labels = torch.Tensor(
sequence).float(), torch.Tensor(labels).long()

optimizer.zero_grad()

Expand All @@ -113,7 +120,7 @@ def transform_func(image_ray):

# Calculate the loss
loss = criterion(predictions, labels)

# backward pass
loss.backward()
# update weights
Expand Down Expand Up @@ -141,8 +148,8 @@ def __call__(self, received_sample):
sample = torch.cat((pad, sample), dim=0)

# Resize to (length, height, width)
sample = torch.reshape(sample, [sample.size()[0], sample.size()[1], sample.size()[2]])

sample = torch.reshape(
sample, [sample.size()[0], sample.size()[1], sample.size()[2]])

# Do the same for the labels
labels = torch.Tensor(labels)
Expand All @@ -154,8 +161,9 @@ def __call__(self, received_sample):

if __name__ == '__main__':
parser = argparse.ArgumentParser(description='Train a resnet model')
parser.add_argument('--dataroot', required=True, type=str, help='path to the root data directory')
parser.add_argument('--dataroot', required=True, type=str,
help='path to the root data directory')
parser.add_argument('--maxepochs', default=100, type=int)
args = parser.parse_args()

main(args)
main(args)
Loading
Loading