Skip to content

PhysiMax/mctransport

Repository files navigation

MCTRANSPORT Project

License: MIT Coverage

Installation

It requires Python and git.
Tested on Python 3.10-3.12.

# (Optional) Create and activate a virtual environment:
python -m venv .venv
# Windows (PowerShell):
. .\.venv\Scripts\Activate.ps1
# macOS/Linux:
# source .venv/bin/activate

After cloning the repository:

cd <project-directory>
# Install the package and runtime dependencies:
pip install .
# Or install the editable version (this is also optional):
# pip install -e .[dev]

Running Tests

If not installed dev dependencies yet:

pip install -e .[dev]
# or: pip install -r requirements.txt
# Run all tests
pytest
# Example for running only one test file
pytest tests/test_cli.py
# Example for running a single test function
pytest tests/test_cli.py::test_absorption_only_json_output

Coverage is configured in pytest.ini, for this reason the command pytest is enough to also get the coverage report.


Using the CLI

After installing the package (with pip install .), the user can use two console scripts. To see their help:

  • mctransport -h;
  • mctransport-graph -h.
    Or via Python:
  • python -m mctransport.cli -h;
  • python -m mctransport.graph_cli -h.

Physical Background

This project aims to model transport in a homogeneous isotropic medium.
For now the only physical phenomenon taken into consideration is the pure absorption one without any scattering and sources. In the future these things could be implemented in the program.

A particle (photon, neutron, etc...) travels a random straight free path L, if $L \geq d$, where d represents the slab thickness, the particle is transmitted, otherwise it is absorbed.

Beer-Lambert Law

In a homogeneous isotropic absorbing medium, the transmission probability, that is the probability that a particle travels a distance d without interacting, is defined as:

where d, as said before, is the distance/thickness of the medium to cross, and λ is the mean free path (called lam in the code).
d and λ must have the same units.
This expression is also known considering the attenuation coefficient $\mu = \frac{1}{\lambda}$, so the transmission can also be written as:

In the limit cases for T we have: $T(0) = 1$ and $\lim_{d \to \infty} T(d) = 0$.

Mean Free Path

The mean free path λ represents the average distance a particle travels before being absorbed.
It is defined as:

where $\Sigma = n \sigma$ is the macroscopic absorption cross section, that represents the probability per unit path length that a particle will be absorbed. Here, σ is the microscopic absorption cross section, and n is the number density of absorbing particles.

Free Path L

The free path L follows an exponential distribution with mean λ:

where the mean and the variance are and . With the property:

Monte Carlo

The simulation considers N independent particles.
For each particle:

  • It samples a free path L from the exponential distribution;
  • If $L \geq d$, the particle is transmitted;
  • If $L &lt; d$, the particle is absorbed.

It also samples $L_i \sim \mathrm{Exp}(\text{mean}=\lambda)$ and defines the transmission indicator:

Since each is Bernoulli with parameter p = T(d).
The transmission estimator is the sample mean, so:

The number of transmitted particles follows a binomial distribution, for this reason the standard error (SE) of the Monte Carlo result is:


Program Structure

All the modules of the program are inside src/mctransport:

Some common parameter rules are the following:

  • n, n_particles: strictly positive and finite integer (booleans are rejected);
  • distance (d): non-negative and finite;
  • mean_free_path (λ): strictly positive and finite;
  • rng: numpy.random.Generator.

distance and mean_free_path must have the same units.

Random Number Generation (RNG) Module

The src/mctransport/rng.py module contains a function for random number generation.

Function

  • sample_free_path(n, mean_free_path, rng)
    • It generates n free path lengths from an exponential distribution with mean mean_free_path.

The output is a 1D NumPy array of n free path lengths (non-negative floats).


Physics Module

The src/mctransport/physics.py module contains a function that computes the transmission probability.

Function

  • beer_lambert_transmission(distance, mean_free_path)
    • It gives the transmission probability: T(d) = exp(-d / λ).

The function returns a float value in [0, 1].


Simulation Module

The src/mctransport/simulate.py module contains a function for running the Monte Carlo transmission simulation using the other two modules together.

Function

  • simulate_absorption_only(n_particles, distance, mean_free_path, rng)
    • By creating free paths L from an exponential distribution and by counting particles with $L \geq d$, it simulates the transmission.

The output is a float in [0, 1].


Command-Line Interface Module

The src/mctransport/cli.py module gives a CLI to run the simulation from the terminal without Python code.

Usage

mctransport absorption-only -N <N> -d <distance> -l <mean_free_path> [options]

The required parameters are the following:

  • -N or --n-particles: It must be a positive finite integer. Scientific notation like '1e5' is accepted;
  • -d or --distance: non-negative and finite;
  • -l or --lambda or --mean-free-path: strictly positive and finite.

The possible options are:

  • Seed:
    • --seed: int, RNG seed, if not specified is 'null' as default;
  • Verbosity (mutually exclusive):
    • --verbose: print parameters + numeric result;
    • --terse: print only the numeric result;
    • --silent: no console output.
  • Output formats:
    • --precision: int, how many decimal digits for the numeric result (default: 6);
    • --json: print result as JSON (also used for file output, it overrides the verbosity);
    • --output PATH: write output to file (JSON if --json, otherwise CSV).

Some Examples

mctransport absorption-only -N 1e5 -d 3 -l 2 --seed 42
# Transmission fraction: 0.224480
mctransport absorption-only -N 100000 -d 3.0 -l 2.0 --seed 42 --verbose
# Simulation: absorption-only
# N = 100,000
# d = 3.0
# mean_free_path = 2.0
# seed = 42
# Transmission fraction: 0.224480
# JSON on console and written to result.json in the current directory
mctransport absorption-only -N 1e5 -d 7 -l 2 --seed 24 --json --output result.json
# On console printed:
# Transmission fraction: 0.029110
# On result.json printed:
# {"simulation": "absorption-only", "n_particles": 100000, "distance": 7.0, "mean_free_path": 2.0, "seed": 24, "transmission": 0.02911}
# CSV file and terse on console
mctransport absorption-only -N 50000 -d 1.5 -l 0.8 --seed 123 --terse --precision 5 --output result.csv
# On console printed:
# 0.15318
# On result.csv printed:
# simulation,n_particles,distance,mean_free_path,seed,transmission
# absorption-only,50000,1.5,0.8,123,0.15318

Important: directories for --output must already exist; the program does not attempt to create missing directories and will exit with error 3 if they do not exist.


Graph Module

The src/mctransport/graph_cli.py script runs a sweep simulation of distances.
It compares the Monte Carlo transmission with the Beer-Lambert law.
It also writes a CSV with the data and a PNG plot (and it saves them inside ./results/ by default).
It uses independent RNG seeds per point: for each distance point (with index i), the seed is set to seed + i so that every row is reproducible with the results obtained with src/mctransport/cli.py.

Usage

Programmatic use (Python):
With this first method the user can modify the parameters in the Python code and directly call run_sweep():

# Example of changing parameters 
import numpy as np
from mctransport.graph_cli import run_sweep

run_sweep(
    N=50_000,
    lam=3.0,
    seed=5678,
    d_vals=np.linspace(0.0, 1.0, 7),
    outdir="output_directory",
)

Parameters:

  • N: It must be a strictly positive finite integer. Scientific notation is not accepted;
  • lam: strictly positive and finite;
  • seed: int, RNG seed is 'seed + i';
  • d_vals: np.ndarray, non-negative and finite values;
  • outdir: str or Path, output folder (created if missing).

CLI:
The second method consists in using the CLI:

# Example, if some parameters are not defined it takes the default ones.
mctransport-graph
# Example, all the parameters defined
mctransport-graph --N 200000 --lam 1.5 --seed 7 --dmin 0 --dmax 6 --points 25 --outdir output_directory

This second method builds an equally spaced grid of distances and creates d_vals as np.linspace(dmin, dmax, points).

The script produces two outputs:

  • CSV: results_absorption_sweep.csv with columns 'distance', 'T_mc', 'T_theory', 'SE';
  • PNG: results_absorption_sweep.png (MC points with ±2*SE to consider 95% of expected statistical variation; and theoretical curve).

Example Output

Example of the plot produced by the command:

mctransport-graph --N 200000 --lam 1.5 --seed 7 --dmin 0 --dmax 6 --points 25 --outdir output_directory

Absorption sweep example

Tests (100% coverage)

The tests for all the modules are located in tests/.

About

This project is part of the Software and Computing for Applied Physics course.

Topics

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages