A file-based pipeline for efficient batch processing and modeling of hyperspectral images.
Project description
SpecPipe
A high-performance, file-based pipeline for batch processing and modeling of hyperspectral images.
SpecPipe streamlines the batch testing and optimization of hyperspectral analysis workflows. It provides a structured framework to apply various image processing techniques (calibration, baseline correction, denoising, feature engineering, etc.) in combination with various machine learning models. The pipeline employs a comprehensive full-factorial design to evaluate all method combinations and generates standard reports on performance metrics, residual analysis, influence anlaysis and visualizations.
Core features:
- Batch processing: Automate numerous data processing and modeling workflows in a single batch operation.
- File-based: A resumable, file-based processing pipeline enabling result validation and break tolerance.
- High-performance: Optimized for hyperspectral images with minimal memory consumption and options of GPU acceleration and pipeline-level multiprocessing.
- Simple extensible integration: Intuitive data management and straightforward integration for custom processing functions and Scikit-learn-style models.
Table of Contents
Installation
Follow these steps to install the project:
-
Prerequisites: Ensure you have Python 3.9 or higher installed.
-
Install from PyPI (Recommended):
pip install specpipe
-
Install from source (for development):
git clone https://github.com/siwei66/SpecPipe.git cd SpecPipe pip install -e specpipe
Usage
1. Prepare mock spectral experiment data
-
Create a directory for mock experiment data (The example uses a temporary directory):
import tempfile data_dir = tempfile.mkdtemp(prefix="specpipe_example_")
-
Create mock data:
from specpipe import create_test_raster, create_test_roi_xml create_test_raster(f"{data_dir}/example.tif") create_test_roi_xml(f"{data_dir}/example_roi.xml")
2. Configure your experiment data
2.1 Create a spectral experiment instance
-
Here we use the same directory as report directory:
report_dir = data_dir
-
Create a SpecExp instance:
from specpipe import SpecExp exp = SpecExp(report_dir)
The instance stores and organizes the data loading configurations of an experiment, which faciliates lazy-loading.
- Check report directory:
exp.report_directory
2.2. Experiment group management
-
Add experiment groups:
exp.add_groups(['group_1', 'group_2'])
-
Check groups:
exp.ls_groups()
-
Remove a group:
exp.rm_group('group_2')
2.3. Raster image management
-
Add raster images:
exp.add_images_by_name( image_name = 'example', image_directory = data_dir, group = 'group_1' )
-
Check added images:
exp.ls_images()
2.4. Region of interest (ROI) management
-
Load image ROIs using suffix to image names:
exp.add_rois_by_suffix("_roi.xml", data_dir, "group_1")
-
Remove ROIs by name:
exp.rm_rois(roi_name='ROI_10')
-
Load ROIs to a image using ROI files by paths:
exp.add_rois_by_file([f"{data_dir}/example_roi.xml"], image_name="example.tif", group="group_1")
-
Check added ROIs:
exp.ls_rois()
The example xml ROI file contains 10 ROIs.
- Check sample ROIs:
exp.ls_rois_sample()
2.5. Sample labels and target values
2.5.1 Set sample labels
-
Get current sample label dataframe:
labels = exp.ls_labels()
-
Set new sample labels in the dataframe: Here we use sample_1, sample_2 ... sample_10
labels.iloc[:,1] = [f'sample_{str(i+1)}' for i in range(len(labels))]
-
Update sample labels using the updated dataframe:
exp.sample_labels = labels
-
Check sample labels:
exp.ls_labels()
2.5.2 Set target values
-
List target value dataframe:
targets = exp.ls_sample_targets()
-
Create mock target values for regression and update target dataframe: Here we use 1 to 10
targets['Target_value'] = [i for i in range(len(targets))]
-
Load target values from updated target dataframe:
exp.sample_targets_from_df(targets)
-
Check target values:
exp.ls_targets()
3. Design testing pipeline
-
SpecPipe follows a structured data processing workflow with these sequential data levels:
Raster image data -> ROI spectra -> ROI statistics -> Traits to model
-
The technical data levels in SpecPipe includes:
Images: 0 - "image", input image path and output processed image path. Image pixel spectra: 1 - "pixel_spec", 1D spectrum of image pixel (simple) 2 - "pixel_specs_array", 2D spectra array of image pixels (fast) 3 - "pixel_specs_tensor", 2D spectra tensor of image pixels (fast) 4 - "pixel_hyperspecs_tensor", 2D hyperspectra tensor of image pixels (fastest) (See "rasterop.pixel_apply" - apply processing functions to spectra of image pixels) Image ROIs: 5 - "image_roi", raster with sample ROIs, for spectrum extraction 6 - "roispecs", 2D array of ROI spectra 7 - "spec1d", arbitrary 1D data of samples, e.g. 1D spectra, spectra statistics Models: 8 - "model", model evaluation with standard report output as files -
The corresponding data processing workflow is:
Raster image data: 0 ~ 4 ↓ Extract ROI spectra: 5 - "image_roi" ↓ ROI spectra: 6 - "roispecs" ↓ ROI statistics: 7 - "spec1d" ↓ Model evaluation: 8 - "model"
The processing functions are wrapped in the pipeline according to the specified "data levels". Parallel processes can be added with identical "data level" and "application sequence", and they are arranged using full-factorial approach in the pipeline.
3.1 Create processing pipeline
- Create processing pipeline from SpecExp instance configured above:
from specpipe import SpecPipe pipe = SpecPipe(exp)
3.2 Image processing
-
Create some image processing functions, such as:
-
Standard normal variate:
import numpy as np def snv(v): vmean = np.mean(v, axis=1, keepdims=True) vstd = np.std(v, axis=1, keepdims=True) snv = (v - vmean) / vstd return snv
-
Raw data for performance comparison:
def raw(v): return v
-
Add these processing functions to the pipeline:
pipe.add_process( input_data_level = 'pixel_specs_array', output_data_level = 'pixel_specs_array', application_sequence = 0, method = snv )
-
Or we can specify the data level using the corresponding number:
pipe.add_process(2, 2, 0, raw)
3.3 ROI statistics
-
Import some ROI spectral statistic metrics:
from specpipe import roi_mean from specpipe import roi_median
-
Add these process to the pipeline:
pipe.add_process( input_data_level = 'image_roi', output_data_level = 'spec1d', application_sequence = 0, method = roi_mean )
-
Or specify data level using number:
pipe.add_process(5, 7, 0, roi_median)
3.4 Sample data wrangling
-
Create a function to remove nan and inf values:
def replace_nan(v: np.ndarray) -> np.ndarray: return np.nan_to_num(v, nan=0.0, posinf=0.0, neginf=0.0)
-
Add the process to the pipeline:
pipe.add_process('spec1d', 'spec1d', 0, replace_nan)
-
Check all added processes:
pipe.ls_process()
-
To remove added processes from the pipeline:
pipe.rm_process(method='raw')
Processes can be removed by various criteria, the example removes the function 'raw' by its name.
3.5 Add models to the pipeline
-
Create some models:
from sklearn.linear_model import LinearRegression from sklearn.ensemble import RandomForestRegressor from sklearn.neighbors import KNeighborsRegressor from sklearn.svm import SVR linear_regressor = LinearRegression() rf_regressor = RandomForestRegressor(n_estimators=10) knn_regressor = KNeighborsRegressor(n_neighbors=3) svr = SVR()
-
Add model using "add_process":
pipe.add_process('spec1d', 'model', 1, linear_regressor, validation_method = '10-fold') pipe.add_process(7, 8, 1, rf_regressor, validation_method = '10-fold')
-
Add model using add_model:
pipe.add_model(knn_regressor, validation_method = '10-fold') pipe.add_model(svr, validation_method = '10-fold')
-
Check added models:
pipe.ls_model()
-
Check all processes including models:
pipe.ls_process()
4 Run pipeline
-
Check processing chains of the pipeline:
pipe.ls_chains()
-
Manually test all added processes:
pipe.test_run()
The added processes are also automatically tested before formal run.
-
Run pipeline:
pipe.run()
-
Set resume True to enable resuming:
pipe.run(resume=True)
If the implementation is interrupted or forcibly terminated, running the pipeline again will automatically resume from the last completed step.
5 Running results
-
The pipeline produces following results for every processing chain, including:
• Final and intermediate processing results • Configurations • Validation and application models • Model evaluation reports • Visualization
-
The resulting file structure is as follows:
-
For input data:
data_directory/ ├── SpecExp_configuration/ │ ├── Loading_history/ │ │ ├── Loaded_images.csv │ │ └── Loaded_ROIs.csv │ └── SpecExp_data_configuration.dill ├── Your_rasters.tif └── Your_ROIs.xml
-
For regression tasks, the pipeline generates:
report_directory/ ├── Modeling/ │ └── Model_Evaluation_Reports/ │ ├── Data_chain_Preprocessing_#0_Model_(model label 0)/ │ │ ├── Model_for_application/ │ │ ├── Model_in_validation/ │ │ ├── Validation_results.csv │ │ ├── Regression_performance.csv │ │ ├── Residual_analysis.csv │ │ ├── Influence_analysis.csv │ │ ├── Scatter_plot.png │ │ └── Residual_plot.png │ ├── Data_chain_Preprocessing_#0_Model_(model label 1)/ │ ├── Data_chain_Preprocessing_#1_Model_(model label 0)/ │ ├── Data_chain_Preprocessing_#1_Model_(model label 1)/ │ ├── Preprocessing_#0.txt │ └── Preprocessing_#1.txt ├── Pre_execution_test_data/ ├── Preprocessing/ │ ├── Step_results/ │ ├── PreprocessingChainResult_chain_0.csv │ └── PreprocessingChainResult_chain_1.csv └── test_run/
-
For classification tasks, the pipeline generates:
report_directory/ ├── Modeling/ │ └── Model_Evaluation_Reports/ │ ├── Data_chain_Preprocessing_#0_Model_(model label 0)/ │ │ ├── Model_for_application/ │ │ ├── Model_in_validation/ │ │ ├── Validation_results.csv │ │ ├── Classification_performance.csv │ │ ├── Residual_analysis.csv │ │ ├── Influence_analysis.csv │ │ └── ROC_curve.png │ ├── Data_chain_Preprocessing_#0_Model_(model label 1)/ │ ├── Data_chain_Preprocessing_#1_Model_(model label 0)/ │ ├── Data_chain_Preprocessing_#1_Model_(model label 1)/ │ ├── Preprocessing_#0.txt │ └── Preprocessing_#1.txt ├── Pre_execution_test_data/ ├── Preprocessing/ │ ├── Step_results/ │ ├── PreprocessingChainResult_chain_0.csv │ └── PreprocessingChainResult_chain_1.csv └── test_run/
Contributing
This is an initial release of SpecPipe. Your experience applying this toolset in your specialized field is extremely valuable. Any feedback and contributions are highly welcomed!
- Report bugs: Found an issue? Please open a GitHub issue with details
- Share your domain expertise: Tell us how SpecPipe works (or doesn't work) in your specific application area in discussions
- Suggest features: Have ideas for improvements? Use the GitHub discussions or issues tab
- Submit pull requests: Feel free to fork and submit PRs for bug fixes or small features
- Test and provide feedback: Try it out and let us know about your experience in discussions
License
This project is licensed under the MIT License - see the LICENSE file for details.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file specpipe-0.1.1.tar.gz.
File metadata
- Download URL: specpipe-0.1.1.tar.gz
- Upload date:
- Size: 167.3 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
848480a2ba9356bd089e82992afd5a51e0b35e4505dad7665c447a338f9b78ee
|
|
| MD5 |
b974caa3c6845401c3be8b38eda52edb
|
|
| BLAKE2b-256 |
f17a60c9ebc049fb2e40a65899c812d33443b4e0612149cd76b036dd5d081b24
|
Provenance
The following attestation bundles were made for specpipe-0.1.1.tar.gz:
Publisher:
specpipe_release.yml on siwei66/specpipe
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
specpipe-0.1.1.tar.gz -
Subject digest:
848480a2ba9356bd089e82992afd5a51e0b35e4505dad7665c447a338f9b78ee - Sigstore transparency entry: 614124230
- Sigstore integration time:
-
Permalink:
siwei66/specpipe@7cedca9a1fd8bbefbec215048d10a61c3857cc3b -
Branch / Tag:
refs/tags/v0.1.1 - Owner: https://github.com/siwei66
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
specpipe_release.yml@7cedca9a1fd8bbefbec215048d10a61c3857cc3b -
Trigger Event:
release
-
Statement type:
File details
Details for the file specpipe-0.1.1-py3-none-any.whl.
File metadata
- Download URL: specpipe-0.1.1-py3-none-any.whl
- Upload date:
- Size: 113.7 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
9eedd59b4a9b7f4006dc3b977a2d5cbaf861bd1d9c43159a5e24aee08a1fb4a0
|
|
| MD5 |
f49eaa2b55407bc0f5b80340f7b6529e
|
|
| BLAKE2b-256 |
99aa9a4bfa174d0dda367ce190b9a713e70b66c180fd0493cbfc014c6075d840
|
Provenance
The following attestation bundles were made for specpipe-0.1.1-py3-none-any.whl:
Publisher:
specpipe_release.yml on siwei66/specpipe
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
specpipe-0.1.1-py3-none-any.whl -
Subject digest:
9eedd59b4a9b7f4006dc3b977a2d5cbaf861bd1d9c43159a5e24aee08a1fb4a0 - Sigstore transparency entry: 614124241
- Sigstore integration time:
-
Permalink:
siwei66/specpipe@7cedca9a1fd8bbefbec215048d10a61c3857cc3b -
Branch / Tag:
refs/tags/v0.1.1 - Owner: https://github.com/siwei66
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
specpipe_release.yml@7cedca9a1fd8bbefbec215048d10a61c3857cc3b -
Trigger Event:
release
-
Statement type: