Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
59 commits
Select commit Hold shift + click to select a range
2fc2569
Simple dose calculation
Aug 5, 2025
2f2606d
make deployment
Aug 5, 2025
2b2f38e
beamletFreeOpti
Aug 5, 2025
7a069af
readme: Community example
Aug 5, 2025
ba74258
nested section
Aug 5, 2025
59efcce
boundConstraintsOpti
Aug 5, 2025
5146597
SimpleOptimization
Aug 6, 2025
156fa98
opentps in colab
Aug 7, 2025
3e369fb
requirement
Aug 7, 2025
fd02c9e
ProtonPlanDesign
Aug 7, 2025
5ca6a6e
opentps collab
Aug 8, 2025
f894651
opentps install
Aug 8, 2025
632e49d
requirement
Aug 8, 2025
2780123
simpleOpt_Dicom
Aug 8, 2025
141c1b9
segmentation
Aug 8, 2025
215e767
rigid registration
Aug 8, 2025
a2e6049
morphons registration
Aug 8, 2025
5a2241f
Dose delivery simulation
Aug 8, 2025
12f79e0
dynamic data
Aug 8, 2025
712794c
run all
Aug 11, 2025
fd861fe
new example
Aug 11, 2025
7d12486
cuoy vs transform
Aug 11, 2025
665165a
imageProcessing
Aug 11, 2025
4af7d33
cupy
Aug 11, 2025
d51c7c6
image processing
Aug 11, 2025
36cc96f
tigre
Aug 11, 2025
7fe82a3
cupy
Aug 11, 2025
c112a46
other example
Aug 12, 2025
11648a9
end other example
Aug 12, 2025
7b63ab8
plan optimization
Aug 13, 2025
b5f3727
cupy
Aug 13, 2025
f77881b
conf.py
Aug 13, 2025
78901cf
fixed
Aug 13, 2025
73397db
innstall tigre
Aug 14, 2025
4d31d1a
install tigre
Aug 14, 2025
8ec6b22
install tigre
Aug 14, 2025
f8b87f3
install tigre
Aug 14, 2025
25b0f04
only run some
Aug 18, 2025
933def9
community examples
Aug 18, 2025
57557e6
community examples
Aug 18, 2025
b5ea387
robustnes
Aug 18, 2025
877ce11
cupy
Aug 18, 2025
3264c89
proton plan
Aug 18, 2025
8dbe301
multiple python env
Aug 19, 2025
b8618c8
dose computation
Aug 19, 2025
bcd531a
dose computation
Aug 19, 2025
0681dd7
shared memory
Aug 19, 2025
aeec189
fix bugs
Aug 19, 2025
0894f02
path
Aug 19, 2025
7158277
shared memory
Aug 19, 2025
ee6851b
community example
Aug 20, 2025
f2f9391
template
Aug 20, 2025
d4b14e0
runtime
Aug 21, 2025
f03e714
gitignore
Aug 21, 2025
86fc85b
end runtime
Aug 21, 2025
071f503
time
Aug 22, 2025
3444664
run all
Aug 22, 2025
8cf8d3f
4D
Aug 22, 2025
41841af
template
Aug 22, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
Binary file added .DS_Store
Binary file not shown.
9 changes: 8 additions & 1 deletion .github/workflows/deploy_gh_page.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ on :
push :
branches :
- main
- update_examples

permissions:
id-token: write
Expand All @@ -23,6 +24,12 @@ jobs :
python -m pip install --upgrade pip
pip install sphinx sphinx-gallery sphinx-book-theme
pip install -r requirements.txt
git clone https://gitlab.com/openmcsquare/opentps.git
pip install ./opentps
pip install --upgrade pip setuptools wheel
pip install tigre[cpu] # CPU-only install if available


- name: Build the docs
run: |
make html
Expand All @@ -40,4 +47,4 @@ jobs :
uses: actions/deploy-pages@v4
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
artifact_name: github-pages
artifact_name: github-pages
16 changes: 16 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,21 @@ _build
auto_examples/**
!auto_examples/**/*.ipynb
!auto_examples/**/
examples/**/output/

.idea

auto_community/**
!auto_community/**/*.ipynb
!auto_community/**/


community/**
!community/**/*.py
!community/**/*.rst
!community/**/

examples/**
!examples/**/*.py
!examples/**/*.rst
!examples/**/
Binary file added _static/OpenTPS_logo_dark_big.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion _templates/my_header.html
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@
var fileName = pathParts.pop().replace('.html', '.ipynb');

// Check if the forelast word is 'auto_examples'
if (foreforelastWord === 'auto_examples'&& fileName !== 'index.ipynb') {
if ((foreforelastWord === 'auto_examples'||foreforelastWord === 'auto_community')&& fileName !== 'index.ipynb') {
// Show the button
var colabButton = document.getElementById('colab-button');
colabButton.style.display = 'inline-block';
Expand Down
356 changes: 356 additions & 0 deletions auto_community/CommunityExample/SimpleDoseComputationAndOptOnCT.ipynb

Large diffs are not rendered by default.

104 changes: 104 additions & 0 deletions auto_community/Template/run_template.ipynb
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"\n# Template Example\n\nThis is a minimal example showing how to contribute to the\nCommunity Gallery. It just generates some random data and plots it.\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Setting up the environment in google collab\n First you need to change the type of execution in the bottom left from processor to GPU. Then you can run the example.\n\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"import sys\nif \"google.colab\" in sys.modules:\n from IPython import get_ipython\n get_ipython().system('git clone https://gitlab.com/openmcsquare/opentps.git')\n get_ipython().system('pip install ./opentps')\n get_ipython().system('pip install scipy==1.10.1')\n get_ipython().system('pip install cupy-cuda12x')\n import opentps"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"imports\n\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"import numpy as np\nimport matplotlib.pyplot as plt"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Step 1. Generate random data\n\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"x = np.linspace(0, 10, 100)\ny = np.sin(x) + 0.2 * np.random.randn(100)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Step 2. Plot the results\nTo display your plot in the Sphinx gallery, make sure plt.show() is the last line of your code cell.\n\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"plt.figure()\nplt.plot(x, y, label=\"noisy sine\")\nplt.legend()\nplt.title(\"Random sine example\")\nplt.xlabel(\"x\")\nplt.ylabel(\"y\")\nplt.show()"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.11.13"
}
},
"nbformat": 4,
"nbformat_minor": 0
}
227 changes: 227 additions & 0 deletions auto_examples/DoseComputation/run_SimpleDoseCalculation.ipynb
Original file line number Diff line number Diff line change
@@ -0,0 +1,227 @@
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"\n# Simple dose computation\nauthor: OpenTPS team\n\nIn this example we are going to create a generic CT and use the MCsquare dose calculator to compute the dose image\n\nrunning time: ~ 7 minute\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Setting up the environment in google collab\n First you need to change the type of execution in the bottom left from processor to GPU. Then you can run the example.\n\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"import sys\nif \"google.colab\" in sys.modules:\n from IPython import get_ipython\n get_ipython().system('git clone https://gitlab.com/openmcsquare/opentps.git')\n get_ipython().system('pip install ./opentps')\n get_ipython().system('pip install scipy==1.10.1')\n get_ipython().system('pip install cupy-cuda12x')\n import opentps"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"imports\n\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"import numpy as np\nimport os\nfrom matplotlib import pyplot as plt\nimport math"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"import the needed opentps.core packages\n\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"from opentps.core.data.images import CTImage\nfrom opentps.core.data.images import ROIMask\nfrom opentps.core.data.plan import ProtonPlanDesign\nfrom opentps.core.data import DVH\nfrom opentps.core.data import Patient\nfrom opentps.core.io import mcsquareIO\nfrom opentps.core.io.scannerReader import readScanner\nfrom opentps.core.processing.doseCalculation.doseCalculationConfig import DoseCalculationConfig\nfrom opentps.core.processing.doseCalculation.protons.mcsquareDoseCalculator import MCsquareDoseCalculator\nfrom opentps.core.processing.imageProcessing.resampler3D import resampleImage3DOnImage3D,resampleImage3D"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Generic CT creation\nwe will first create a generic CT of a box fill with water and air\n\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"ctCalibration = readScanner(DoseCalculationConfig().scannerFolder)\nbdl = mcsquareIO.readBDL(DoseCalculationConfig().bdlFile)\n\npatient = Patient()\npatient.name = 'Patient'\n\nctSize = 150\n\nct = CTImage()\nct.name = 'CT'\nct.patient = patient\n\nhuAir = -1024.\nhuWater = ctCalibration.convertRSP2HU(1.)\ndata = huAir * np.ones((ctSize, ctSize, ctSize))\ndata[:, 50:, :] = huWater\nct.imageArray = data"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Region of interest\nwe will now create a region of interest wich is a small 3D box of size 20*20*20\n\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"roi = ROIMask()\nroi.patient = patient\nroi.name = 'TV'\nroi.color = (255, 0, 0) # red\ndata = np.zeros((ctSize, ctSize, ctSize)).astype(bool)\ndata[65:85, 65:85, 65:85] = True\nroi.imageArray = data"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Configuration of MCsquare\nto configure Mcsquare we need to calibrate it with the CT calibration obtained above\n\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"mc2 = MCsquareDoseCalculator()\nmc2.beamModel = bdl\nmc2.ctCalibration = ctCalibration\nmc2.nbPrimaries = 1e7"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Plan Creation\nwe will now create a plan and create one beam\n\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"# Design plan\nbeamNames = [\"Beam1\",\"Beam2\",\"Beam3\"]\ngantryAngles = [0.,90.,270.]\ncouchAngles = [0.,0.,0.]\n\n# Generate new plan\nplanDesign = ProtonPlanDesign()\nplanDesign.ct = ct\nplanDesign.targetMask = roi\nplanDesign.gantryAngles = gantryAngles\nplanDesign.beamNames = beamNames\nplanDesign.couchAngles = couchAngles\nplanDesign.calibration = ctCalibration\nplanDesign.spotSpacing = 5.0\nplanDesign.layerSpacing = 5.0\nplanDesign.targetMargin = 5.0\n\nplan = planDesign.buildPlan() # Spot placement\nplan.PlanName = \"NewPlan\""
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Center of mass\nHere we look at the part of the 3D CT image where \"stuff is happening\" by getting the CoM. We use the function resampleImage3DOnImage3D to the same array size for both images.\n\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"roi = resampleImage3DOnImage3D(roi, ct)\nCOM_coord = roi.centerOfMass\nCOM_index = roi.getVoxelIndexFromPosition(COM_coord)\nZ_coord = COM_index[2]\n\nimg_ct = ct.imageArray[:, :, Z_coord].transpose(1, 0)\ncontourTargetMask = roi.getBinaryContourMask()\nimg_mask = contourTargetMask.imageArray[:, :, Z_coord].transpose(1, 0)\n\n#Output path \noutput_path = 'Output'\nif not os.path.exists(output_path):\n os.makedirs(output_path)\n\nimage = plt.imshow(img_ct,cmap='Blues')\nplt.colorbar(image)\nplt.contour(img_mask,colors=\"red\")\nplt.title(\"Created CT with ROI\")\nplt.text(5,40,\"Air\",color= 'black')\nplt.text(5,100,\"Water\",color = 'white')\nplt.text(71,77,\"TV\",color ='red')\nplt.savefig(os.path.join(output_path, 'SimpleCT.png'),format = 'png')\nplt.show()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Dose Computation\nWe now use the MCsquare dose calculator to compute the dose of the created plan\n\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"doseImage = mc2.computeDose(ct, plan)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"img_dose = resampleImage3DOnImage3D(doseImage, ct)\nimg_dose = img_dose.imageArray[:, :, Z_coord].transpose(1, 0)\nscoringSpacing = [2, 2, 2]\nscoringGridSize = [int(math.floor(i / j * k)) for i, j, k in zip([150,150,150], scoringSpacing, [1,1,1])]\nroiResampled = resampleImage3D(roi, origin=ct.origin, gridSize=scoringGridSize, spacing=scoringSpacing)\ntarget_DVH = DVH(roiResampled, doseImage)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"fig, ax = plt.subplots(1, 2, figsize=(12, 5))\nax[0].imshow(img_ct, cmap='gray')\nax[0].imshow(img_mask, alpha=.2, cmap='binary') # PTV\ndose = ax[0].imshow(img_dose, cmap='jet', alpha=.2)\ncbar = plt.colorbar(dose, ax=ax[0])\ncbar.set_label('Dose(Gy)')\nax[1].plot(target_DVH.histogram[0], target_DVH.histogram[1], label=target_DVH.name)\nax[1].set_xlabel(\"Dose (Gy)\")\nax[1].set_ylabel(\"Volume (%)\")\nplt.grid(True)\nplt.legend()\nplt.savefig(os.path.join(output_path, 'SimpleDose.png'), format = 'png')\nplt.show()"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"print('D95 = ' + str(target_DVH.D95) + ' Gy')\nprint('D5 = ' + str(target_DVH.D5) + ' Gy')\nprint('D5 - D95 = {} Gy'.format(target_DVH.D5 - target_DVH.D95))"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.11.13"
}
},
"nbformat": 4,
"nbformat_minor": 0
}
Loading
Loading