Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
0e6b33a
add missing plotly deps and fix ignore list
KedoKudo Aug 15, 2025
3dc5df4
update lock
KedoKudo Aug 15, 2025
42dfebb
move file_hanlder module into package
KedoKudo Aug 15, 2025
87a3667
fix using deprecated API issues
KedoKudo Aug 16, 2025
c1ab38f
fix deprecated api calls in dev notebook
KedoKudo Aug 16, 2025
0b73ff7
cont fix deprecated api in notebook
KedoKudo Aug 16, 2025
f1b706e
cont fix deprecated api issue in notebook
KedoKudo Aug 16, 2025
497b170
cont fix notebooks with deprecated apis
KedoKudo Aug 16, 2025
a9b7659
remove generated files
KedoKudo Aug 16, 2025
badc26e
add ignore list to stop tracking generated files
KedoKudo Aug 16, 2025
b73a197
update loading tutorial
KedoKudo Aug 16, 2025
d5f2717
update deprecated api usage
KedoKudo Aug 17, 2025
2a662cb
rename notebook
KedoKudo Aug 17, 2025
4b940f4
rename with number
KedoKudo Aug 17, 2025
d4731bf
update tutorial 02
KedoKudo Aug 17, 2025
d8f8d7e
update tutorial 03
KedoKudo Aug 17, 2025
6fe1d93
update tutorial 03 output cell
KedoKudo Aug 17, 2025
4487bf0
update readme
KedoKudo Aug 17, 2025
19842e9
remove tokens
KedoKudo Aug 17, 2025
56f5e84
pixi deps update
KedoKudo Aug 18, 2025
734a6d9
update pixi deps
KedoKudo Aug 18, 2025
fab9222
Merge branch 'next' into add_artifact_removal
KedoKudo Aug 18, 2025
9adf153
update lock file
KedoKudo Aug 18, 2025
5e8a72d
move notebook to notebooks folder
KedoKudo Aug 18, 2025
706a0a8
Update src/neutron_geomcorr/file_handler.py
KedoKudo Aug 18, 2025
92dbb24
Update src/neutron_geomcorr/file_handler.py
KedoKudo Aug 18, 2025
f64f0d0
fix copilot error edits
KedoKudo Aug 18, 2025
d448fee
add new deps for the new prototype notebook
KedoKudo Aug 20, 2025
36344d2
add new deps and update lock file
KedoKudo Aug 20, 2025
6894b77
add cylindrical correction development notebook
KedoKudo Aug 21, 2025
3ae3100
add hyperspectra radiograph analysis block
KedoKudo Aug 21, 2025
1422ac3
update output cells
KedoKudo Aug 21, 2025
a63f51f
updated development notebook
KedoKudo Aug 21, 2025
4397b05
add derivation markdown file
KedoKudo Aug 21, 2025
21cf576
Few minor changes to improve my understanding of the algo used.
JeanBilheux Aug 29, 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
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
pyproject.toml.bak
_version.py
.ruff_cache/
.pytest_cache/
.pytest_cache
htmlcov/

### Linux ###
Expand Down
2 changes: 1 addition & 1 deletion .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ repos:
rev: v5.0.0
hooks:
- id: check-added-large-files
args: [--maxkb=8192]
args: [--maxkb=30000]
- id: check-json
- id: check-merge-conflict
- id: check-toml
Expand Down
54 changes: 30 additions & 24 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,37 +1,33 @@
[![Documentation Status](https://readthedocs.org/projects/cylindricalgeometrycorrection/badge/?version=latest)](https://cylindricalgeometrycorrection.readthedocs.io/en/latest/?badge=latest)

# neutron-geomcorr (Neutron Geometry Correction)

[![Documentation Status](https://readthedocs.org/projects/cylindricalgeometrycorrection/badge/?version=latest)](https://cylindricalgeometrycorrection.readthedocs.io/en/latest/?badge=latest)

Formerly known as CylindricalGeometryCorrection, this library performs geometric corrections for neutron transmission imaging of cylindrical samples (both solid and hollow).

# Principle
Any homegenous cylindrical sample placed in a beam (neutron for example) will show a much higher transmission signal
near the edge seen by the beam, compare to the center. This is simply due to the fact that the beam has to go through
more material at the center compare to the side.
## Principle

Any **homogeneous** cylindrical sample placed in a beam (neutron for example) will show a much higher transmission signal near the edge seen by the beam, compare to the center. This is simply due to the fact that the beam has to go through more material at the center compare to the side.

ATTENTION: This library only works with cylinder placed in the vertical position!
> ATTENTION: This library only works with **cylinder** placed in the **vertical** position!

The following figure illustrate this.

![image](documentation/source/_static/homogeneous_cylinder_2d_view.png)

In order to correctly analyze data for those samples, one must cancel this cylindrical effect by "making" the sample
flat related to the direction of the beam.

The user needs to specify the position of the center as well as the radius of the cylinder. The program will then produce
an image corresponding to the same rectangular sample.

In order to correctly analyze data for those samples, one must cancel this cylindrical effect by "making" the sample flat related to the direction of the beam.
The user needs to specify the position of the center as well as the radius of the cylinder.
The program will then produce an image corresponding to the same rectangular sample.
Such samples are called homogeneous because they are made of only one uniform and homogeneous material.

But program also work with inhomogeneous sample for which the cylinder is hollow such as shown here.

![image](documentation/source/_static/inhomogeneous_cylinder_2d_view.png)

Program works the same way, user needs to specify center and inner and outer radius of material sample.

# Installation
## Installation

### Using Pixi (Recommended for Development)

## Using Pixi (Recommended for Development)
```bash
# Install pixi if you haven't already
curl -fsSL https://pixi.sh/install.sh | bash
Expand All @@ -47,17 +43,23 @@ pixi install
pixi run python
```

## Using pip
### Using pip

```bash
pip install neutron-geomcorr
```

## Using conda
> After package is published to PyPI.

### Using conda

```bash
conda install -c neutronimaging neutron-geomcorr
```

# Usage
> After package is published to conda.

## Usage

```python
from neutron_geomcorr.geometry_correction import GeometryCorrection
Expand All @@ -76,19 +78,22 @@ o_cgc.correct()
corrected_images = o_cgc.list_data_corrected
```

# Development
## Development

### Running Tests

## Running Tests
```bash
pixi run test
```

## Building Documentation
### Building Documentation

```bash
pixi run build-docs
```

## Building Package
### Building Package

```bash
# For PyPI
pixi run pypi-build
Expand All @@ -97,5 +102,6 @@ pixi run pypi-build
pixi run conda-build
```

# Tutorial
## Tutorial

It's recommended to follow the notebook tutorials in the `notebooks/` directory to learn how to use the library
2 changes: 0 additions & 2 deletions codecov.yml

This file was deleted.

128 changes: 128 additions & 0 deletions documentation/derivation.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
# Cylindrical Geometry Correction for Transmission Data

This document presents the methodology for applying cylindrical geometry correction to transmission data, specifically in the context of neutron or X-ray imaging where Beer-Lambert law governs the attenuation of intensity through a material.

---

## Background: Beer-Lambert Law for Transmission

The transmitted intensity $ I(x, y) $ at a position $(x, y)$ through a material is described by the Beer-Lambert law:

$$
I(x, y) = I_0 \cdot e^{-\mu \cdot L(x, y)}
$$

where:

- $ I(x, y) $ is the transmitted intensity at position $(x, y)$,
- $ I_0 $ is the incident (background) intensity,
- $ \mu $ is the linear attenuation coefficient (accounting for both absorption and scattering),
- $ L(x, y) $ is the chord length through the material at position $(x, y)$.

For a vertical cylindrical sample, the system can be simplified by considering only the horizontal coordinate $ x $, assuming uniformity along $ y $:

$$
I(x) = I_0 \cdot e^{-\mu \cdot L(x)}
$$

where $ L(x) $ is the chord length through the cylinder at position $ x $.

---

### Transmission and Attenuation Coefficient

The normalized transmission $ T(x) $, also known as the normalized radiograph, is defined as the ratio of transmitted intensity to incident intensity:

$$
T(x) = \frac{I(x)}{I_0} = e^{-\mu \cdot L(x)}
$$

From this relation, the attenuation coefficient $ \mu $ can be calculated as:

$$
\mu = - \frac{\ln(T(x))}{L(x)}
$$

---

## Practical Considerations

In practice, ideal background measurements $ I_0 $ may not be available or may be imperfect, resulting in transmission values $ T(x) > 1 $, which leads to negative or non-physical values for $ \mu $. To address this, two robust methods for estimating $ \mu $ are presented below.

---

#### Method 1: Discrete Method (Two-Column Approach)

This method leverages transmission values at two distinct positions $ x_1 $ and $ x_2 $ on the cylinder to estimate a physically meaningful attenuation coefficient.

Given:

$$
T(x_1) = e^{-\mu \cdot L(x_1)} \quad \text{and} \quad T(x_2) = e^{-\mu \cdot L(x_2)}
$$

Taking the ratio:

$$
\frac{T(x_1)}{T(x_2)} = \frac{e^{-\mu \cdot L(x_1)}}{e^{-\mu \cdot L(x_2)}} = e^{-\mu \cdot (L(x_1) - L(x_2))}
$$

Solving for $ \mu $:

$$
\mu = -\frac{1}{L(x_2) - L(x_1)} \cdot \ln\left(\frac{T(x_1)}{T(x_2)}\right)
$$

**Interpretation:** This approach ensures that the calculated attenuation coefficient $ \mu $ is always positive and physically meaningful, as it relies on relative transmission differences rather than absolute values. The choice of $ x_1 $ and $ x_2 $ should correspond to positions with reliable transmission data.

---

#### Method 2: Iterative Method (Global Regression with Nuisance Term)

An alternative approach involves performing a global regression across all spatial positions $ x $ to estimate $ \mu $ while accounting for nuisance parameters (such as background fluctuations or instrumental effects). This iterative method fits the model:

$$
T(x) \approx e^{-\mu \cdot L(x)} \cdot N(x)
$$

where $ N(x) $ represents a nuisance term that captures deviations from ideal background normalization.

The regression optimizes the parameters $ \mu $ and $ N(x) $ to minimize the discrepancy between measured and modeled transmissions across the entire dataset. This method is particularly useful when background measurements are noisy or non-uniform.

---

### Correction Application per Wavelength (TOF Bin)

It is important to note that the attenuation coefficient $ \mu $ and the corresponding correction factor are wavelength-dependent (i.e., vary with Time-of-Flight (TOF) bins). Therefore, the correction must be applied separately for each wavelength bin to accurately account for energy-dependent attenuation.

---

## Cylindrical Sample Thickness Correction

Once $ \mu $ is determined, the goal is to transform the measured transmission $ T(x) $ corresponding to the chord length $ L(x) $ at position $ x $ to a uniform thickness corresponding to the cylinder diameter $ D $.

Given:

$$
T(x) = e^{-\mu \cdot L(x)}
$$

We define the corrected transmission for uniform thickness $ D $ as:

$$
T^D(x) = e^{-\mu \cdot D}
$$

The correction factor $ C(x) $ to be applied to the measured transmission is:

$$
C(x) = \frac{T^D(x)}{T(x)} = e^{-\mu \cdot (D - L(x))}
$$

This factor adjusts the transmission data as if the sample thickness were uniform and equal to the diameter $ D $.

> **Note:** Since the attenuation coefficient $ \mu $ is derived using differences in chord lengths, the correction factor $ C(x) $ is dimensionless and physically consistent.

---

This methodology provides a robust framework for correcting cylindrical sample transmission data, enabling accurate attenuation coefficient estimation and uniform thickness correction across all wavelengths.
Loading
Loading