diff --git a/README.md b/README.md
index cfd4c52..6aab848 100644
--- a/README.md
+++ b/README.md
@@ -1,76 +1,77 @@
-[](https://dosimetry.pages.psi.ch/tracketch/)
+[](https://jbrage.github.io/tracketch/)
[](LICENSE)
[](https://www.python.org/)
[](tests/)
-[](http://hits.dwyl.com/jbrage/tracketch)
-
-
# tracketch
A Python toolkit for simulating ion tracks in CR-39 plastic nuclear track
-detectors. Given an ion species, energy, and etching conditions, **tracketch**
-predicts the track countours, diameter, and depth that would be observed under an
-optical microscope after chemical etching.
-
-
-
-
+detectors. Given an ion species, energy, and etching conditions, `tracketch`
+predicts the track countours, diameter and length for a given etching duration.
+The work is published in the article
+[A unified model for etched-track formation in CR-39 detectors using amorphous
+track structure theory](https://papers.ssrn.com/sol3/papers.cfm?abstract_id=6469212)
+by Jeppe Brage Christensen.
> **Note** - due to its dependency on
-> [libamtrack](https://libamtrack.github.io/), **tracketch** currently runs on
+> [libamtrack](https://libamtrack.github.io/), `tracketch` currently runs on
> **Linux only**. Most Windows installations support WSL installations.
+
+
+
+
+ |
+
+
+
+
+Cite as
+```bibtex
+@article{christensen2026unified,
+ title={A unified model for etched-track formation in CR-39 detectors using amorphous track structure theory},
+ author={Christensen, Jeppe Brage},
+ journal={SSRN preprint http://dx.doi.org/10.2139/ssrn.6469212},
+ year={2026}
+}
+```
-> **Note** - This version only supports simulations of ion impinging perpendicular to the CR39 detector surface. Support for 3D track geometries and non-axisymmetric effects is planned for future releases.
-> Furthermore, this etch-rate model is calibrated to the detector type and etching conditions used in [Dörschel et al (2003)](https://www.sciencedirect.com/science/article/abs/pii/S1350448702000471). For other detector types and etching conditions, the calibration workflow described in the documentation can be used to re-calibrate the model against experimental data.
+> **Note** - This version only supports simulations of ion impinging
+> perpendicular to the CR39 detector surface. Support for 3D track geometries
+> and non-axisymmetric effects is planned for future releases.
+> Furthermore, this etch-rate model is calibrated to the detector type and
+> etching conditions used in
+> [Dörschel et al (2003)](https://www.sciencedirect.com/science/article/abs/pii/S1350448702000471).
+> For other detector types and etching conditions, the calibration workflow
+> described in the documentation can be used to re-calibrate the model against
+> experimental data.
## Documentation
-The documentation is hosted online and includes user guides, API references, and examples:
-[Online documentation](https://dosimetry.pages.psi.ch/tracketch/)
+The documentation is hosted online and includes user guides, API references,
+and examples: [Documentation](https://jbrage.github.io/tracketch/)
+A PDF version of the documentation is also available in the `docs/` directory: [tracketch_docs.pdf](docs/tracketch.pdf)
## How it works
The simulation follows the same physics chain as the real experiment:
-1. **Radial dose distribution (RDD)**: the ion deposits energy radially via
- delta-electrons. tracketch computes the 2-D dose map along the ion path using
- models from libamtrack (e.g. Cucinotta) and SRIM stopping-power tables.
+1. **Dose maps**: the ion deposits energy radially via delta-electrons.
+ `tracketch` computes the dose map along the ion path using amorphous track
+ structure models from `libamtrack` (e.g. Cucinotta) and slows down the ion
+ in the CR-39 detector using `SRIM` stopping-power tables.
2. **Etch-rate model**: a calibrated function converts local dose to local
- etch velocity *V(D)*. The bulk (undamaged) material etches at a slower
- constant rate *V_bulk*.
-3. **Wavefront propagation**: the etchant front is propagated from the
- detector surface into the bulk using shortest-path algorithms (Dijkstra or
- Fast Marching). The result is an *arrival-time map*.
+ etch velocity $v_d$. The bulk (undamaged) material etches at a slower
+ constant rate $v_\text{bulk}$.
+3. **Wavefront propagation**: the etchant front is propagated from the detector
+ surface into the bulk using shortest-path algorithms (Dijkstra or Fast
+ Marching), analogous to the propagation of a wavefront. The result is an
+ *arrival-time map*.
4. **Track observables**: iso-time contours of the arrival-time map give the
etched track shape at any desired etching duration.
-## Etch-rate model selection
-
-tracketch uses a single default calibration model for all particles:
-`"Doerschel_etching"`.
-
-- The etch-rate model is not selected by `particle_name`.
-- Particle selection affects stopping-power and dose physics, not which
- etch-rate model file is loaded.
-- Users can still load a different etch-rate model explicitly (for example,
- a custom re-calibrated model).
-
-```python
-from tracketch import TrackSimulator, load_etchrate_model
-
-# Explicitly load a custom calibration model if needed.
-etch_model = load_etchrate_model("my_custom_model")
-
-sim = TrackSimulator(
- particle_name="12C",
- start_energy_MeV_u=270.0,
- etch_model=etch_model,
-)
-```
## Installation
@@ -79,13 +80,14 @@ sim = TrackSimulator(
git clone /tracketch
cd tracketch
-# create a virtual environment and install
+# create a virtual environment and install; change "all" to "numba" or "cpp"
+# to only install one backend or to skip testing/docs dependencies
python3 -m venv .venv
source .venv/bin/activate
-pip install -e ".[numba]"
+pip install -e ".[all]"
```
-This installs tracketch with the Numba-accelerated Dijkstra backend, which
+This installs `tracketch` with the Numba-accelerated Dijkstra backend, which
works out of the box on any Linux machine.
### Optional: C++ Dijkstra backend
@@ -94,11 +96,10 @@ To also install the faster CPP backend, use
pip install -e ".[numba,cpp]"
cd tracketch/wavefront/dijkstra/cpp
python setup_dijkstra.py build_ext --inplace
-cd -
```
## Minimal working example
-Check out the tracketch examples in the [`examples/`](examples/) directory.
+Check out the `tracketch` examples in the [`examples/`](examples/) directory.
```python
import matplotlib.pyplot as plt
from tracketch import TrackSimulator
@@ -142,7 +143,7 @@ and `symbol` is the element symbol:
The available ions depend on the **stopping-power source**:
-- **`stopping_power_source="SRIM"` (default)** - uses tabulated SRIM data.
+- **`stopping_power_source="SRIM"` (default)** - uses tabulated `SRIM` data.
Only the following particles are supported:
```python
import tracketch
@@ -152,8 +153,8 @@ The available ions depend on the **stopping-power source**:
Attempting any other particle raises a `ValueError` with a suggestion to
switch source.
-- **`stopping_power_source="libamtrack"`** - uses the libamtrack/PSTAR
- parametrisation. Accepts any nuclide name recognised by libamtrack, e.g.
+- **`stopping_power_source="libamtrack"`** - uses the `libamtrack`
+ parametrisation. Accepts any nuclide name recognised by `libamtrack`, e.g.
`"56Fe"`, `"238U"`, `"28Si"`.
```python
@@ -180,7 +181,7 @@ Pass them as `material_name="CR39"` (default) or `material_name="water"`.
## Simulation grid
-The simulation operates on a 2D cylindrical grid (*r*, *z*) with these defaults:
+The simulation operates on a cylindrical grid (*r*, *z*) with these defaults:
| Parameter | Default | Description |
|-----------|---------|-------------|
@@ -214,11 +215,16 @@ publication-quality results consider doubling `n_points_r` and `n_points_z`.
Full API reference and usage guides can be re-built with Sphinx:
```bash
+pip install -e ".[docs]"
cd docs
make html
```
-
Then open `docs/_build/html/index.html` in your browser.
+Or
+```bash
+make pdlatex
+```
+to build the PDF version of the documentation.
## Project layout
@@ -229,7 +235,8 @@ Then open `docs/_build/html/index.html` in your browser.
│ │ └── stopping_power/ SRIM data tables and parsing
│ ├── etching/ EtchRateModel -- dose -> etch velocity
│ ├── simulation/ TrackSimulator -- full model
-│ └── wavefront/ Track contour calculation through arrival-time solvers (Dijkstra, FMM)
+│ └── wavefront/ Track contour calculation through arrival-time
+│ solvers (Dijkstra, FMM)
├── calibration/ Etch-model calibration against experimental data
├── examples/ Runnable example scripts
├── tests/ pytest test suite
diff --git a/calibration/benchmark_bragg_corrections.py b/calibration/benchmark_bragg_corrections.py
index baa2f97..fe1fee7 100644
--- a/calibration/benchmark_bragg_corrections.py
+++ b/calibration/benchmark_bragg_corrections.py
@@ -44,7 +44,7 @@
PARTICLES = ["1H", "4He", "7Li", "12C"]
SEEDS = [11, 22]
POPSIZE = 50
- MAXITER = 300
+ MAXITER = 50
TOL = 1e-6
OUTPUT_DIR_NAME = "bragg_benchmark"
else:
@@ -60,18 +60,14 @@
SMOOTHNESS_WEIGHT = 0.001
-# More general seeded initialization for V(d):
-# - build a broader log-dose anchor grid
-# - perturb log-velocity increments per seed
-ANCHOR_MIN_DOSE_GY = 1e2
-ANCHOR_MAX_DOSE_GY = 1e9
-# Piecewise anchor placement with highest density in 1e5..1e7 Gy.
-ANCHOR_MID_MIN_DOSE_GY = 1e4
-ANCHOR_DENSE_MIN_DOSE_GY = 1e5
-ANCHOR_DENSE_MAX_DOSE_GY = 1e8
-ANCHOR_DENSITY_WEIGHTS = (2.0, 3.0, 30.0, 5.0)
-# Run one or multiple anchor-count configurations.
-ANCHOR_COUNT_USER_OPTIONS = [40]
+# Match run_Vd_calibration.py anchor buckets exactly.
+# d_Gy = concat([
+# logspace(2, 4, endpoint=False, num=1),
+# logspace(4, 5, endpoint=False, num=2),
+# logspace(5, 8, endpoint=False, num=8),
+# logspace(8, 9, endpoint=True, num=2),
+# ])
+ANCHOR_COUNT_USER_OPTIONS = [13]
INIT_LOG_INCREMENT_NOISE_STD = 0.08
# Run debris damping in separate configurations.
@@ -123,52 +119,24 @@ def _save_track_shape_pngs(models_dict: dict, run_dir: Path) -> list[str]:
def _build_user_anchor_dose_grid(anchor_count_user: int) -> np.ndarray:
- """Build piecewise log-dose anchors with dense spacing in 1e5..1e8 Gy."""
- if anchor_count_user < 4:
- return np.logspace(
- np.log10(ANCHOR_MIN_DOSE_GY),
- np.log10(ANCHOR_MAX_DOSE_GY),
- anchor_count_user,
- )
-
- dose_edges = np.asarray(
+ """Build the same anchor-dose grid as run_Vd_calibration.py."""
+ user_doses = np.concatenate(
[
- ANCHOR_MIN_DOSE_GY,
- ANCHOR_MID_MIN_DOSE_GY,
- ANCHOR_DENSE_MIN_DOSE_GY,
- ANCHOR_DENSE_MAX_DOSE_GY,
- ANCHOR_MAX_DOSE_GY,
- ],
- dtype=float,
+ np.logspace(2, 4, endpoint=False, num=1),
+ np.logspace(4, 5, endpoint=False, num=2),
+ np.logspace(5, 8, endpoint=False, num=8),
+ np.logspace(8, 9, endpoint=True, num=2),
+ ]
)
- weights = np.asarray(ANCHOR_DENSITY_WEIGHTS, dtype=float)
+ user_doses = np.unique(user_doses)
+ user_doses = np.sort(user_doses)
- seg_counts = np.maximum(
- 1, np.floor(anchor_count_user * weights / weights.sum()).astype(int)
- )
- while int(seg_counts.sum()) < anchor_count_user:
- seg_counts[int(np.argmax(weights))] += 1
- while int(seg_counts.sum()) > anchor_count_user:
- reducible = np.where(seg_counts > 1)[0]
- if reducible.size == 0:
- break
- seg_counts[int(reducible[np.argmin(weights[reducible])])] -= 1
-
- segments: list[np.ndarray] = []
- for i, n_pts in enumerate(seg_counts):
- seg = np.logspace(
- np.log10(dose_edges[i]),
- np.log10(dose_edges[i + 1]),
- int(n_pts),
- endpoint=(i == len(seg_counts) - 1),
+ if anchor_count_user != len(user_doses):
+ raise ValueError(
+ "anchor_count_user must match run_Vd_calibration anchor count "
+ f"({len(user_doses)}), got {anchor_count_user}"
)
- segments.append(seg)
-
- user_doses = np.sort(np.concatenate(segments))
- # Enforce exact endpoints for reproducibility and requested full range.
- user_doses[0] = ANCHOR_MIN_DOSE_GY
- user_doses[-1] = ANCHOR_MAX_DOSE_GY
return user_doses
diff --git a/calibration/figures_calibration/debris_comparison_12C.png b/calibration/figures_calibration/debris_comparison_12C.png
new file mode 100644
index 0000000..bdca3a7
Binary files /dev/null and b/calibration/figures_calibration/debris_comparison_12C.png differ
diff --git a/calibration/figures_calibration/debris_comparison_1H.png b/calibration/figures_calibration/debris_comparison_1H.png
new file mode 100644
index 0000000..b5603bd
Binary files /dev/null and b/calibration/figures_calibration/debris_comparison_1H.png differ
diff --git a/calibration/figures_calibration/debris_comparison_4He.png b/calibration/figures_calibration/debris_comparison_4He.png
new file mode 100644
index 0000000..039520d
Binary files /dev/null and b/calibration/figures_calibration/debris_comparison_4He.png differ
diff --git a/calibration/figures_calibration/debris_comparison_7Li.png b/calibration/figures_calibration/debris_comparison_7Li.png
new file mode 100644
index 0000000..cd542a6
Binary files /dev/null and b/calibration/figures_calibration/debris_comparison_7Li.png differ
diff --git a/calibration/figures_calibration/track_shape_12C.png b/calibration/figures_calibration/track_shape_12C.png
new file mode 100644
index 0000000..7c23449
Binary files /dev/null and b/calibration/figures_calibration/track_shape_12C.png differ
diff --git a/calibration/figures_calibration/track_shape_1H.png b/calibration/figures_calibration/track_shape_1H.png
new file mode 100644
index 0000000..435c6a5
Binary files /dev/null and b/calibration/figures_calibration/track_shape_1H.png differ
diff --git a/calibration/figures_calibration/track_shape_4He.png b/calibration/figures_calibration/track_shape_4He.png
new file mode 100644
index 0000000..27878b3
Binary files /dev/null and b/calibration/figures_calibration/track_shape_4He.png differ
diff --git a/calibration/figures_calibration/track_shape_7Li.png b/calibration/figures_calibration/track_shape_7Li.png
new file mode 100644
index 0000000..b63a563
Binary files /dev/null and b/calibration/figures_calibration/track_shape_7Li.png differ
diff --git a/calibration/results/bragg_benchmark/bragg_0/debris_fit/anchors_13/seed_11/track_shape_12C.png b/calibration/results/bragg_benchmark/bragg_0/debris_fit/anchors_13/seed_11/track_shape_12C.png
new file mode 100644
index 0000000..69d906d
Binary files /dev/null and b/calibration/results/bragg_benchmark/bragg_0/debris_fit/anchors_13/seed_11/track_shape_12C.png differ
diff --git a/calibration/results/bragg_benchmark/bragg_0/debris_fit/anchors_13/seed_11/track_shape_1H.png b/calibration/results/bragg_benchmark/bragg_0/debris_fit/anchors_13/seed_11/track_shape_1H.png
new file mode 100644
index 0000000..0e5510d
Binary files /dev/null and b/calibration/results/bragg_benchmark/bragg_0/debris_fit/anchors_13/seed_11/track_shape_1H.png differ
diff --git a/calibration/results/bragg_benchmark/bragg_0/debris_fit/anchors_13/seed_11/track_shape_4He.png b/calibration/results/bragg_benchmark/bragg_0/debris_fit/anchors_13/seed_11/track_shape_4He.png
new file mode 100644
index 0000000..26d2377
Binary files /dev/null and b/calibration/results/bragg_benchmark/bragg_0/debris_fit/anchors_13/seed_11/track_shape_4He.png differ
diff --git a/calibration/results/bragg_benchmark/bragg_0/debris_fit/anchors_13/seed_11/track_shape_7Li.png b/calibration/results/bragg_benchmark/bragg_0/debris_fit/anchors_13/seed_11/track_shape_7Li.png
new file mode 100644
index 0000000..e5123b3
Binary files /dev/null and b/calibration/results/bragg_benchmark/bragg_0/debris_fit/anchors_13/seed_11/track_shape_7Li.png differ
diff --git a/calibration/results/bragg_benchmark/bragg_0/debris_fit/anchors_13/seed_22/track_shape_12C.png b/calibration/results/bragg_benchmark/bragg_0/debris_fit/anchors_13/seed_22/track_shape_12C.png
new file mode 100644
index 0000000..d102230
Binary files /dev/null and b/calibration/results/bragg_benchmark/bragg_0/debris_fit/anchors_13/seed_22/track_shape_12C.png differ
diff --git a/calibration/results/bragg_benchmark/bragg_0/debris_fit/anchors_13/seed_22/track_shape_1H.png b/calibration/results/bragg_benchmark/bragg_0/debris_fit/anchors_13/seed_22/track_shape_1H.png
new file mode 100644
index 0000000..43521d5
Binary files /dev/null and b/calibration/results/bragg_benchmark/bragg_0/debris_fit/anchors_13/seed_22/track_shape_1H.png differ
diff --git a/calibration/results/bragg_benchmark/bragg_0/debris_fit/anchors_13/seed_22/track_shape_4He.png b/calibration/results/bragg_benchmark/bragg_0/debris_fit/anchors_13/seed_22/track_shape_4He.png
new file mode 100644
index 0000000..9b2cdf4
Binary files /dev/null and b/calibration/results/bragg_benchmark/bragg_0/debris_fit/anchors_13/seed_22/track_shape_4He.png differ
diff --git a/calibration/results/bragg_benchmark/bragg_0/debris_fit/anchors_13/seed_22/track_shape_7Li.png b/calibration/results/bragg_benchmark/bragg_0/debris_fit/anchors_13/seed_22/track_shape_7Li.png
new file mode 100644
index 0000000..bc52b3a
Binary files /dev/null and b/calibration/results/bragg_benchmark/bragg_0/debris_fit/anchors_13/seed_22/track_shape_7Li.png differ
diff --git a/calibration/results/bragg_benchmark/bragg_0/debris_without/anchors_13/seed_11/track_shape_12C.png b/calibration/results/bragg_benchmark/bragg_0/debris_without/anchors_13/seed_11/track_shape_12C.png
new file mode 100644
index 0000000..24a96b0
Binary files /dev/null and b/calibration/results/bragg_benchmark/bragg_0/debris_without/anchors_13/seed_11/track_shape_12C.png differ
diff --git a/calibration/results/bragg_benchmark/bragg_0/debris_without/anchors_13/seed_11/track_shape_1H.png b/calibration/results/bragg_benchmark/bragg_0/debris_without/anchors_13/seed_11/track_shape_1H.png
new file mode 100644
index 0000000..3be1713
Binary files /dev/null and b/calibration/results/bragg_benchmark/bragg_0/debris_without/anchors_13/seed_11/track_shape_1H.png differ
diff --git a/calibration/results/bragg_benchmark/bragg_0/debris_without/anchors_13/seed_11/track_shape_4He.png b/calibration/results/bragg_benchmark/bragg_0/debris_without/anchors_13/seed_11/track_shape_4He.png
new file mode 100644
index 0000000..455f235
Binary files /dev/null and b/calibration/results/bragg_benchmark/bragg_0/debris_without/anchors_13/seed_11/track_shape_4He.png differ
diff --git a/calibration/results/bragg_benchmark/bragg_0/debris_without/anchors_13/seed_11/track_shape_7Li.png b/calibration/results/bragg_benchmark/bragg_0/debris_without/anchors_13/seed_11/track_shape_7Li.png
new file mode 100644
index 0000000..130021f
Binary files /dev/null and b/calibration/results/bragg_benchmark/bragg_0/debris_without/anchors_13/seed_11/track_shape_7Li.png differ
diff --git a/calibration/results/bragg_benchmark/bragg_0/debris_without/anchors_13/seed_22/track_shape_12C.png b/calibration/results/bragg_benchmark/bragg_0/debris_without/anchors_13/seed_22/track_shape_12C.png
new file mode 100644
index 0000000..d59860b
Binary files /dev/null and b/calibration/results/bragg_benchmark/bragg_0/debris_without/anchors_13/seed_22/track_shape_12C.png differ
diff --git a/calibration/results/bragg_benchmark/bragg_0/debris_without/anchors_13/seed_22/track_shape_1H.png b/calibration/results/bragg_benchmark/bragg_0/debris_without/anchors_13/seed_22/track_shape_1H.png
new file mode 100644
index 0000000..acb3eef
Binary files /dev/null and b/calibration/results/bragg_benchmark/bragg_0/debris_without/anchors_13/seed_22/track_shape_1H.png differ
diff --git a/calibration/results/bragg_benchmark/bragg_0/debris_without/anchors_13/seed_22/track_shape_4He.png b/calibration/results/bragg_benchmark/bragg_0/debris_without/anchors_13/seed_22/track_shape_4He.png
new file mode 100644
index 0000000..0716070
Binary files /dev/null and b/calibration/results/bragg_benchmark/bragg_0/debris_without/anchors_13/seed_22/track_shape_4He.png differ
diff --git a/calibration/results/bragg_benchmark/bragg_0/debris_without/anchors_13/seed_22/track_shape_7Li.png b/calibration/results/bragg_benchmark/bragg_0/debris_without/anchors_13/seed_22/track_shape_7Li.png
new file mode 100644
index 0000000..363ee64
Binary files /dev/null and b/calibration/results/bragg_benchmark/bragg_0/debris_without/anchors_13/seed_22/track_shape_7Li.png differ
diff --git a/calibration/results/bragg_benchmark/bragg_3/debris_fit/anchors_13/seed_11/track_shape_12C.png b/calibration/results/bragg_benchmark/bragg_3/debris_fit/anchors_13/seed_11/track_shape_12C.png
new file mode 100644
index 0000000..0c03404
Binary files /dev/null and b/calibration/results/bragg_benchmark/bragg_3/debris_fit/anchors_13/seed_11/track_shape_12C.png differ
diff --git a/calibration/results/bragg_benchmark/bragg_3/debris_fit/anchors_13/seed_11/track_shape_1H.png b/calibration/results/bragg_benchmark/bragg_3/debris_fit/anchors_13/seed_11/track_shape_1H.png
new file mode 100644
index 0000000..96dffcf
Binary files /dev/null and b/calibration/results/bragg_benchmark/bragg_3/debris_fit/anchors_13/seed_11/track_shape_1H.png differ
diff --git a/calibration/results/bragg_benchmark/bragg_3/debris_fit/anchors_13/seed_11/track_shape_4He.png b/calibration/results/bragg_benchmark/bragg_3/debris_fit/anchors_13/seed_11/track_shape_4He.png
new file mode 100644
index 0000000..024d7ed
Binary files /dev/null and b/calibration/results/bragg_benchmark/bragg_3/debris_fit/anchors_13/seed_11/track_shape_4He.png differ
diff --git a/calibration/results/bragg_benchmark/bragg_3/debris_fit/anchors_13/seed_11/track_shape_7Li.png b/calibration/results/bragg_benchmark/bragg_3/debris_fit/anchors_13/seed_11/track_shape_7Li.png
new file mode 100644
index 0000000..c5cd3df
Binary files /dev/null and b/calibration/results/bragg_benchmark/bragg_3/debris_fit/anchors_13/seed_11/track_shape_7Li.png differ
diff --git a/calibration/results/bragg_benchmark/bragg_3/debris_without/anchors_13/seed_11/track_shape_12C.png b/calibration/results/bragg_benchmark/bragg_3/debris_without/anchors_13/seed_11/track_shape_12C.png
new file mode 100644
index 0000000..946d7a7
Binary files /dev/null and b/calibration/results/bragg_benchmark/bragg_3/debris_without/anchors_13/seed_11/track_shape_12C.png differ
diff --git a/calibration/results/bragg_benchmark/bragg_3/debris_without/anchors_13/seed_11/track_shape_1H.png b/calibration/results/bragg_benchmark/bragg_3/debris_without/anchors_13/seed_11/track_shape_1H.png
new file mode 100644
index 0000000..2c11d68
Binary files /dev/null and b/calibration/results/bragg_benchmark/bragg_3/debris_without/anchors_13/seed_11/track_shape_1H.png differ
diff --git a/calibration/results/bragg_benchmark/bragg_3/debris_without/anchors_13/seed_11/track_shape_4He.png b/calibration/results/bragg_benchmark/bragg_3/debris_without/anchors_13/seed_11/track_shape_4He.png
new file mode 100644
index 0000000..1a7cca3
Binary files /dev/null and b/calibration/results/bragg_benchmark/bragg_3/debris_without/anchors_13/seed_11/track_shape_4He.png differ
diff --git a/calibration/results/bragg_benchmark/bragg_3/debris_without/anchors_13/seed_11/track_shape_7Li.png b/calibration/results/bragg_benchmark/bragg_3/debris_without/anchors_13/seed_11/track_shape_7Li.png
new file mode 100644
index 0000000..0bf960b
Binary files /dev/null and b/calibration/results/bragg_benchmark/bragg_3/debris_without/anchors_13/seed_11/track_shape_7Li.png differ
diff --git a/calibration/results/bragg_benchmark/bragg_3/debris_without/anchors_13/seed_22/track_shape_12C.png b/calibration/results/bragg_benchmark/bragg_3/debris_without/anchors_13/seed_22/track_shape_12C.png
new file mode 100644
index 0000000..1bdbfe1
Binary files /dev/null and b/calibration/results/bragg_benchmark/bragg_3/debris_without/anchors_13/seed_22/track_shape_12C.png differ
diff --git a/calibration/results/bragg_benchmark/bragg_3/debris_without/anchors_13/seed_22/track_shape_1H.png b/calibration/results/bragg_benchmark/bragg_3/debris_without/anchors_13/seed_22/track_shape_1H.png
new file mode 100644
index 0000000..8e9d4bf
Binary files /dev/null and b/calibration/results/bragg_benchmark/bragg_3/debris_without/anchors_13/seed_22/track_shape_1H.png differ
diff --git a/calibration/results/bragg_benchmark/bragg_3/debris_without/anchors_13/seed_22/track_shape_4He.png b/calibration/results/bragg_benchmark/bragg_3/debris_without/anchors_13/seed_22/track_shape_4He.png
new file mode 100644
index 0000000..74e106a
Binary files /dev/null and b/calibration/results/bragg_benchmark/bragg_3/debris_without/anchors_13/seed_22/track_shape_4He.png differ
diff --git a/calibration/results/bragg_benchmark/bragg_3/debris_without/anchors_13/seed_22/track_shape_7Li.png b/calibration/results/bragg_benchmark/bragg_3/debris_without/anchors_13/seed_22/track_shape_7Li.png
new file mode 100644
index 0000000..1daf6df
Binary files /dev/null and b/calibration/results/bragg_benchmark/bragg_3/debris_without/anchors_13/seed_22/track_shape_7Li.png differ
diff --git a/calibration/results/bragg_benchmark/bragg_5/debris_without/anchors_13/seed_11/track_shape_12C.png b/calibration/results/bragg_benchmark/bragg_5/debris_without/anchors_13/seed_11/track_shape_12C.png
new file mode 100644
index 0000000..a7d5acd
Binary files /dev/null and b/calibration/results/bragg_benchmark/bragg_5/debris_without/anchors_13/seed_11/track_shape_12C.png differ
diff --git a/calibration/results/bragg_benchmark/bragg_5/debris_without/anchors_13/seed_11/track_shape_1H.png b/calibration/results/bragg_benchmark/bragg_5/debris_without/anchors_13/seed_11/track_shape_1H.png
new file mode 100644
index 0000000..0519755
Binary files /dev/null and b/calibration/results/bragg_benchmark/bragg_5/debris_without/anchors_13/seed_11/track_shape_1H.png differ
diff --git a/calibration/results/bragg_benchmark/bragg_5/debris_without/anchors_13/seed_11/track_shape_4He.png b/calibration/results/bragg_benchmark/bragg_5/debris_without/anchors_13/seed_11/track_shape_4He.png
new file mode 100644
index 0000000..321e689
Binary files /dev/null and b/calibration/results/bragg_benchmark/bragg_5/debris_without/anchors_13/seed_11/track_shape_4He.png differ
diff --git a/calibration/results/bragg_benchmark/bragg_5/debris_without/anchors_13/seed_11/track_shape_7Li.png b/calibration/results/bragg_benchmark/bragg_5/debris_without/anchors_13/seed_11/track_shape_7Li.png
new file mode 100644
index 0000000..4a01f63
Binary files /dev/null and b/calibration/results/bragg_benchmark/bragg_5/debris_without/anchors_13/seed_11/track_shape_7Li.png differ
diff --git a/calibration/run_Vd_calibration.py b/calibration/run_Vd_calibration.py
index 4a98e58..fd07992 100644
--- a/calibration/run_Vd_calibration.py
+++ b/calibration/run_Vd_calibration.py
@@ -71,8 +71,8 @@ def starting_guess_v_um_h(
if final_fit:
# Final-fit profile aligned with benchmark settings
- de_popsize = 50
- de_maxiter = 50
+ de_popsize = 60
+ de_maxiter = 200
de_tol = 1e-6
de_mutation = (0.5, 1.4)
de_recombination = 0.9
@@ -100,10 +100,10 @@ def starting_guess_v_um_h(
d_Gy = np.concatenate(
[
# Match benchmark anchor buckets exactly.
- np.logspace(2, 4, endpoint=False, num=1),
- np.logspace(4, 5, endpoint=False, num=2),
- np.logspace(5, 8, endpoint=False, num=10),
- np.logspace(8, 9, endpoint=True, num=3),
+ np.logspace(2, 4, endpoint=False, num=2),
+ np.logspace(4, 5, endpoint=False, num=3),
+ np.logspace(5, 8, endpoint=False, num=9),
+ np.logspace(8, 9, endpoint=True, num=2),
]
)
d_Gy = np.unique(d_Gy) # Remove duplicates
@@ -208,9 +208,7 @@ def starting_guess_v_um_h(
# uncertainty: when anchors saturate at V_max, this is the most relevant
# constraint on the saturation velocity.
if np.isfinite(etch_model.V_max_um_h):
- etch_model.V_max_uncertainty_um_h = float(
- unc["velocity_uncertainties_um_h"][-1]
- )
+ etch_model.V_max_uncertainty_um_h = float(unc["velocity_uncertainties_um_h"][-1])
# Save results
etch_model.name = CALIBRATED_MODEL_NAME
@@ -222,11 +220,14 @@ def starting_guess_v_um_h(
for entry in sub_dict.values():
entry["simulator"].recalculate_from_current_etch_model()
+folder_name = "figures_calibration" if final_fit else "figures_calibration_dev"
+os.makedirs(folder_name, exist_ok=True)
+
if objective_mode in ["both", "shape"]:
figs = plot_track_shapes(models_dict["track_shape"], xscale="linear")
shape_keys = list(models_dict["track_shape"].keys())
for i, particle in enumerate(shape_keys):
- figs[i].savefig(f"figures/track_shape_{particle}.png", dpi=300)
+ figs[i].savefig(f"{folder_name}/track_shape_{particle}.png", dpi=300)
# Debris comparison: contours with vs without damping
debris_figs = plot_track_shapes_debris_comparison(
@@ -234,15 +235,13 @@ def starting_guess_v_um_h(
)
for i, particle in enumerate(shape_keys):
debris_figs[i].savefig(
- f"figures/debris_comparison_{particle}.png",
+ f"{folder_name}/debris_comparison_{particle}.png",
dpi=300,
)
if objective_mode in ["both", "length"]:
figs_by_ion = plot_track_length(models_dict["track_length"])
for ion, fig in figs_by_ion.items():
- folder_name = "figures_calibration" if final_fit else "figures_calibration_dev"
- os.makedirs(folder_name, exist_ok=True)
fig.savefig(f"{folder_name}/track_length_{ion}.png", dpi=300)
# %%
diff --git a/docs/index.rst b/docs/index.rst
index 2587a58..2b90b2c 100644
--- a/docs/index.rst
+++ b/docs/index.rst
@@ -4,6 +4,19 @@ tracketch
A Python toolkit for simulating track formation in CR-39 nuclear track
detectors irradiation with ions.
+The work is published in the article
+`A unified model for etched-track formation in CR-39 detectors using amorphous
+track structure theory
+`_
+by Jeppe Brage Christensen.
+
+.. note::
+
+ Due to its dependency on `libamtrack `_,
+ **tracketch** currently runs on **Linux only**. Most Windows installations
+ support WSL installations.
+
+
.. toctree::
:maxdepth: 2
:caption: User Guide
diff --git a/docs/tracketch.pdf b/docs/tracketch.pdf
new file mode 100644
index 0000000..c76ac16
Binary files /dev/null and b/docs/tracketch.pdf differ
diff --git a/examples/plot_deuteron_etching.py b/examples/plot_deuteron_etching.py
index 953b2ae..2d067ba 100644
--- a/examples/plot_deuteron_etching.py
+++ b/examples/plot_deuteron_etching.py
@@ -19,7 +19,6 @@
result_df = pd.DataFrame()
# iterate through combinations and calculate track radius for each
for energy_MeV_u in tqdm.tqdm(energies_MeV_u, total=len(energies_MeV_u)):
-
# create simulator
sim = TrackSimulator(
particle_name=particle,
@@ -60,4 +59,4 @@
ax.set_xlabel("Removed layer / um")
ax.set_ylabel("Track radius / um")
ax.legend(title="Energy (MeV/u)")
-plt.show()
\ No newline at end of file
+plt.show()
diff --git a/pyproject.toml b/pyproject.toml
index e9a7556..98e8f82 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -29,6 +29,7 @@ dependencies = [
cpp = [
"pybind11>=2.6",
+ "setuptools",
]
numba = [
@@ -58,6 +59,22 @@ dev = [
"sphinx-rtd-theme>=3.0",
]
+all = [
+ "pybind11>=2.6",
+ "setuptools",
+ "numba>=0.57",
+ "numpy<=2.2",
+ "scikit-optimize",
+ "lmfit",
+ "tqdm",
+ "sphinx>=8,<9",
+ "sphinx-rtd-theme>=3.0",
+ "pytest",
+ "pytest-xdist",
+ "ruff",
+ "scikit-image",
+]
+
[tool.setuptools.packages.find]
include = ["tracketch*", "calibration*"]
diff --git a/tracketch/etching/models/Doerschel_etching.json b/tracketch/etching/models/Doerschel_etching.json
index 227f350..6f7c340 100644
--- a/tracketch/etching/models/Doerschel_etching.json
+++ b/tracketch/etching/models/Doerschel_etching.json
@@ -2,137 +2,56 @@
"name": "Doerschel_etching",
"V_bulk_um_h": 1.73,
"V_max_um_h": 100.0,
- "V_max_uncertainty_um_h": 1.855967250581455,
+ "V_max_uncertainty_um_h": 8.322281692861123,
"anchor_doses_Gy": [
0.001,
100.0,
- 1000.0,
10000.0,
- 21544.346900318822,
- 46415.88833612782,
+ 31622.776601683792,
100000.0,
- 125892.54117941661,
- 158489.3192461114,
- 199526.2314968879,
- 251188.6431509582,
- 316227.7660168379,
- 398107.1705534969,
- 501187.2336272725,
- 630957.344480193,
- 794328.2347242822,
- 1000000.0,
- 1258925.411794166,
- 1584893.1924611141,
- 1995262.3149688789,
- 2511886.4315095823,
+ 237137.37056616554,
+ 562341.3251903491,
+ 1333521.432163324,
3162277.6601683795,
- 3981071.7055349695,
- 5011872.336272725,
- 6309573.44480193,
- 7943282.347242822,
- 10000000.0,
- 12589254.117941663,
- 15848931.924611142,
- 19952623.14968883,
- 25118864.315095823,
- 31622776.60168379,
- 39810717.05534969,
- 50118723.36272725,
- 63095734.44801943,
- 79432823.47242822,
+ 7498942.093324558,
+ 17782794.100389227,
+ 42169650.342858225,
100000000.0,
- 177827941.00389227,
- 316227766.01683795,
- 562341325.1903491,
1000000000.0
],
"anchor_velocities_um_h": [
1.73,
- 1.7328702687405895,
- 1.7339645047692596,
- 1.7434761767490754,
- 1.7631598574129839,
- 1.7643176104694462,
- 1.7780496930911076,
- 1.7806528988258397,
- 1.7851436631237203,
- 1.7876655107836708,
- 1.791528192730173,
- 1.793108339985454,
- 1.7961450647151571,
- 1.7991232866984443,
- 1.8022065126715152,
- 1.8042895810027408,
- 1.8081014113861895,
- 1.811758097472675,
- 1.8393955885972841,
- 1.9885271674586098,
- 2.095255470776105,
- 2.167915479463624,
- 2.1773756306992986,
- 2.2309518905994334,
- 2.5710230326271355,
- 2.6221005697701965,
- 2.8288816068936566,
- 2.8288981331652168,
- 2.8289188931525406,
- 2.8289541196038814,
- 3.66997910674418,
- 5.026232991955743,
- 6.548875722414821,
- 6.549381868529469,
- 6.549453800231048,
- 6.5496211075632305,
- 15.725688123505902,
- 20.37687937413121,
- 33.896825754897975,
- 92.79377175559397,
- 92.79836252907275
+ 1.7722745958779738,
+ 1.8055135419252157,
+ 1.934337911217451,
+ 1.9429304969587473,
+ 2.18881199713672,
+ 2.199057329524819,
+ 2.3626080097098825,
+ 2.439817422350564,
+ 2.5871586093465084,
+ 2.954025314321479,
+ 5.75319577937238,
+ 10.089309684704848,
+ 88.30593825964475
],
"anchor_velocity_uncertainties_um_h": [
0.0346,
- 0.03465740537481179,
- 0.034679290095385194,
- 0.03486952353498151,
- 0.4236927643630203,
- 0.4522786840030905,
- 0.9634295927493558,
- 0.9678707649233952,
- 1.22766385536739,
- 1.5674501747298224,
- 2.518978708480592,
- 2.5620093352059774,
- 2.1485475754631698,
- 1.676162425232142,
- 1.5321786404157156,
- 1.401143470715636,
- 1.2163614155059967,
- 1.1815597218571379,
- 2.2719109434863456,
- 2.222032170214383,
- 1.1415288618649497,
- 1.1313512558166554,
- 0.6798563035643918,
- 0.7186825560412243,
- 0.12637033201257614,
- 0.05244201139540393,
- 0.12492740467004745,
- 0.12493335631253878,
- 0.12501051993511508,
- 0.12531035574406074,
- 0.7863491122359768,
- 0.7919221978061346,
- 0.13097751444829642,
- 0.13098763737058938,
- 0.13098907600462098,
- 0.1309924221512646,
- 0.31451376247011803,
- 0.5970276096218552,
- 3.7413647489837474,
- 1.8558754351118794,
- 1.855967250581455
+ 0.4670112122185652,
+ 5.088253928348727,
+ 6.265837626654851,
+ 6.199807196196782,
+ 3.378839880422098,
+ 3.1014721779715413,
+ 0.04725216019419765,
+ 0.23512886353977802,
+ 0.05174317218693017,
+ 0.47407857540789694,
+ 0.1150639155874476,
+ 0.40138504004371267,
+ 8.322281692861123
],
"extrapolation_mode": "pchip",
- "debris_alpha": 10.488453298894855,
- "debris_beta": 1.1733910537622545
+ "debris_alpha": 699.833485055439,
+ "debris_beta": 1.5103813534152948
}
\ No newline at end of file