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 removed .DS_Store
Binary file not shown.
86 changes: 86 additions & 0 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
name: Tests

on:
push:
branches: [ main, development ]
pull_request:
branches: [ main, development ]

jobs:
test:
runs-on: ubuntu-latest
strategy:
matrix:
python-version: [3.8, 3.9, "3.10", "3.11"]

steps:
- uses: actions/checkout@v4

- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v4
with:
python-version: ${{ matrix.python-version }}

- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install -e ".[dev]"

- name: Lint with flake8
run: |
flake8 tmin tests --count --select=E9,F63,F7,F82 --show-source --statistics
flake8 tmin tests --count --exit-zero --max-complexity=10 --max-line-length=127 --statistics

- name: Type check with mypy
run: |
mypy tmin --ignore-missing-imports

- name: Test with pytest
run: |
pytest tests/ --cov=tmin --cov-report=xml --cov-report=html

- name: Upload coverage to Codecov
uses: codecov/codecov-action@v3
with:
file: ./coverage.xml
flags: unittests
name: codecov-umbrella
fail_ci_if_error: false

test-windows:
runs-on: windows-latest
steps:
- uses: actions/checkout@v4

- name: Set up Python 3.10
uses: actions/setup-python@v4
with:
python-version: "3.10"

- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install -e ".[dev]"

- name: Test with pytest
run: |
pytest tests/ --cov=tmin

test-macos:
runs-on: macos-latest
steps:
- uses: actions/checkout@v4

- name: Set up Python 3.10
uses: actions/setup-python@v4
with:
python-version: "3.10"

- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install -e ".[dev]"

- name: Test with pytest
run: |
pytest tests/ --cov=tmin
126 changes: 125 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ sdist/
var/
wheels/
*.egg-info/

.installed.cfg
*.egg

Expand Down Expand Up @@ -56,8 +57,131 @@ Reports/
.pytest_cache/
.coverage
htmlcov/
coverage.xml
.coverage.*
.pytest_cache/

# mypy
.mypy_cache/
.dmypy.json
dmypy.json
dmypy.json

# Coverage reports
htmlcov/
.coverage
coverage.xml
*.cover
.hypothesis/

# pyenv
.python-version

# pipenv
Pipfile.lock

# PEP 582
__pypackages__/

# Celery
celerybeat-schedule
celerybeat.pid

# SageMath parsed files
*.sage.py

# Spyder project settings
.spyderproject
.spyproject

# Rope project settings
.ropeproject

# mkdocs documentation
/site

# Black formatter
.black

# Flake8
.flake8

# Tox
.tox/
.nox/

# Translations
*.mo
*.pot

# Django stuff:
*.log
local_settings.py
db.sqlite3
db.sqlite3-journal

# Flask stuff:
instance/
.webassets-cache

# Scrapy stuff:
.scrapy

# Sphinx documentation
docs/_build/

# PyBuilder
target/

# IPython
profile_default/
ipython_config.py

# Pyre type checker
.pyre/

# pytype static type analyzer
.pytype/

# Cython debug symbols
cython_debug/

# Sublime Text
*.sublime-project
*.sublime-workspace

# Emacs
*~
\#*\#
/.emacs.desktop
/.emacs.desktop.lock
*.elc
auto-save-list
tramp
.\#*

# Windows
Thumbs.db
ehthumbs.db
Desktop.ini
$RECYCLE.BIN/

# Linux
*~

# Temporary files
*.tmp
*.temp
*.bak
*.backup

# Test artifacts
test-results/
test-reports/

# Documentation builds
docs/_build/
docs/build/

# Development tools
.pre-commit-config.yaml
.pre-commit-hooks.yaml
43 changes: 43 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
.PHONY: help install install-dev test test-cov lint format clean build

help: ## Show this help message
@echo "TMIN Development Commands:"
@grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | sort | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-20s\033[0m %s\n", $$1, $$2}'

install: ## Install package in production mode
pip install -e .

install-dev: ## Install package with development dependencies
pip install -e ".[dev]"

test: ## Run tests
python -m pytest tests/ -v

test-cov: ## Run tests with coverage
python -m pytest tests/ --cov=tmin --cov-report=term-missing --cov-report=html -v

test-fast: ## Run only fast tests (exclude slow/integration)
python -m pytest tests/ -m "not slow" -v

lint: ## Run linting checks
flake8 tmin tests
mypy tmin --ignore-missing-imports

format: ## Format code with black
black tmin tests

clean: ## Clean up build artifacts
rm -rf build/
rm -rf dist/
rm -rf *.egg-info/
rm -rf htmlcov/
rm -rf .coverage
rm -rf .pytest_cache/
find . -type d -name __pycache__ -delete
find . -type f -name "*.pyc" -delete

build: ## Build package
python -m build

run-tests: ## Run tests using the test runner script
python run_tests.py
57 changes: 7 additions & 50 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,75 +4,32 @@
<img src="https://github.com/user-attachments/assets/52007543-8109-44ff-845e-c6a809a89a38" alt="TMIN Logo" width="700" />
</p>

[![Downloads per month](https://pepy.tech/badge/tmin/month)](https://pepy.tech/project/tmin)
[![Downloads](https://pepy.tech/badge/tmin)](https://pepy.tech/project/tmin)
[![PyPI version](https://badge.fury.io/py/tmin.svg)](https://badge.fury.io/py/tmin)
![License](https://img.shields.io/pypi/l/tmin)
[![Tests](https://github.com/AndrewTrepagnier/tmin/workflows/Tests/badge.svg)](https://github.com/AndrewTrepagnier/tmin/actions)
[![codecov](https://codecov.io/gh/AndrewTrepagnier/tmin/branch/main/graph/badge.svg)](https://codecov.io/gh/AndrewTrepagnier/tmin)
[![Python Versions](https://img.shields.io/pypi/pyversions/tmin.svg)](https://pypi.org/project/tmin/)
[![Blog](https://img.shields.io/badge/Updates-blog-purple)](https://your-blog-link.com)
[![Blog](https://img.shields.io/badge/dev-wiki-gold)](https://github.com/AndrewTrepagnier/tmin/wiki)
[![Blog](https://img.shields.io/badge/Important-DesignDoc-pink)](https://your-blog-link.com)

TMIN (an abbreviation for "minimum thickness") is an open source software designed to help engineers determine if corroded process piping in refineries and pertrochemical plants are **safe** and **API-compliant** — in seconds.
TMIN (an abbreviation for "minimum thickness") is an open source python package designed to help engineers determine if corroded process piping in refineries and pertrochemical plants are **safe** and **API-compliant** — in seconds.

Many oil and gas companies are faced with maintaining thousands of miles of 100+ year old piping networks supporting multi-million dollar/year processing operations. There is rarely a simple solution to immediately shutdown a process pipe - as these shutdowns more often than not impact other units and cost companies millions in time and resources.

***This is more than a python package, it is a comprehensive engineering decision support system for critical infrastructure safety and operational continuity.***
***TMIN can be used as a conservative and rapid engineering support tool for assessing piping inspection data and determine how close the pipe is to its end of service life.***

---

# Getting Started
# How to install and get started

### Installation:

```bash
pip install tmin
```

### Basic Example:

Suppose the following scenario:

<img width="400" height="250" alt="image" src="https://github.com/user-attachments/assets/1f87dcb1-7d17-4c25-888b-6d9131098ec0"/>

RT findings show your 2" Schedule 40 pipe has 0.060" wall thickness. You need to know if it's safe to operate and how much time remains before pipe retirement.

TMIN can will preform calculations, create visuals, and generate a full assessment report - with only three python functions.

```python
from tmin.core import PIPE
from tmin.visualization import ThicknessVisualizer

# Create pipe instance
pipe = PIPE(
nps=2,
schedule=40,
pressure=300.0,
pressure_class=150,
metallurgy="Intermediate/Low CS",
corrosion_rate=12.0,
yield_stress=33000.0, # 33 ksi for ~22 ksi allowable stress
design_temp=600.0
)

# Analyze thickness and generate report
results = pipe.analysis(
measured_thickness=0.188,
year_inspected=2024,
month_inspected=6 # Last Inspection July, 2024
)
report = pipe.report("TXT") # Options: "CSV", "JSON", "TXT", "IPYNB"

# Create visualizations
visualizer = ThicknessVisualizer()
comparison_chart = visualizer.create_comparison_chart(results, 0.188)
number_line = visualizer.create_thickness_number_line(pipe, results, 0.188)

print(f"Flag: {results['flag']}")
print(f"Status: {results['status']}")
print(f"Report saved: {report['file_path']}")
print(f"Comparison chart: {comparison_chart}")
print(f"Number line visualization: {number_line}")
```

**Results:** Professional report with compliance status, remaining life, and visual analysis in under 30 seconds.

<img width="2170" height="1342" alt="20250807_060427_thickness_analysis_number_line" src="https://github.com/user-attachments/assets/a086ba5a-00b6-45ce-999f-dbbc0b592234" />
Expand Down
1 change: 0 additions & 1 deletion README_EXAMPLES.md

This file was deleted.

21 changes: 0 additions & 21 deletions example_pipe_config.toml

This file was deleted.

Loading
Loading