-
Notifications
You must be signed in to change notification settings - Fork 125
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Adding the helix-example project into demos.
- Loading branch information
Piter Amador Paye Mamani
committed
Dec 30, 2024
1 parent
62ec3d0
commit 7c88fff
Showing
14 changed files
with
983 additions
and
0 deletions.
There are no files selected for viewing
Binary file not shown.
Large diffs are not rendered by default.
Oops, something went wrong.
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
[![Binder](https://mybinder.org/badge_logo.svg)](https://mybinder.org/v2/gh/compiler-research/helix-example/HEAD) | ||
# Helix fitter example | ||
|
||
## Goal | ||
|
||
Particle tracking is an important part of the processing and analysis of data received from particle detectors, such as the Compact Muon Solenoid (CMS). Tracking is the step that determines the momentum of charged particles escaping from the collision point. It identifies individual particles by reconstructing their trajectories from points where charged particle “hits” were measured by the detector and interpreting them.[1] Due to the Lorentz force, charged particles move in a helical motion when affected by the magnetic field (neglecting other effects due to material interactions, etc). This means we can figure out a specific particle trajectory through the detector by fitting a helix function to data points in such a way that the distance from the data points and the helix would be minimized. In mathematical terms, we need to find optimal helix parameters by minimizing a loss function composed of the sum of least squared distances, thus giving the best estimation of these parameters. For this purpose we can use Clad to efficiently minimize the loss function. | ||
|
||
In this repository one can find the code containing one such helix fitter implementation. | ||
|
||
## Content | ||
|
||
Besides the main fitter code, there are a few more files: | ||
|
||
- Documentation.pdf - a more in depth explanation of the code and methods used. | ||
- Helix.ipynb - a Jupyter notebook containing the code and the documentation comments. Can be used to try out the code online but is considerably slower. | ||
- Graph_from_file.ipynb - accompanies Helix.ipynb. Reads from the output.txt (produced by Helix.ipynb) and plots the results. | ||
|
||
|
||
## Usage | ||
|
||
One can compile the files with: | ||
|
||
``` | ||
clang++ main.cc -o main -I /full/path/to/clad/include/ -fplugin=/full/path/to/lib/clad.so -I /full/path/to/kokkos-4.3.01/include | ||
``` | ||
Running the code and plotting the output can be done by: | ||
|
||
``` | ||
./main | python3 graph.py | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
#pragma once | ||
|
||
#include <cmath> | ||
|
||
inline double DistanceSquare(double x1, double y1, double z1, double x2, double y2, double z2) | ||
{ | ||
return (x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2) + (z1 - z2) * (z1 - z2); | ||
} | ||
|
||
inline double Distance(double x1, double y1, double z1, double x2, double y2, double z2) | ||
{ | ||
return std::sqrt(DistanceSquare(x1, y1, z1, x2, y2, z2)); | ||
} | ||
|
||
inline double DistanceSquareA(double v[3], double x2, double y2, double z2) | ||
{ | ||
return DistanceSquare(v[0], v[1], v[2], x2, y2, z2); | ||
} | ||
|
||
inline double DistanceA(double v[3], double x2, double y2, double z2) | ||
{ | ||
return Distance(v[0], v[1], v[2], x2, y2, z2); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
channels: | ||
- conda-forge | ||
dependencies: | ||
- xeus-cling | ||
- clad | ||
- matplotlib |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,90 @@ | ||
#pragma once | ||
|
||
#include <cmath> | ||
#include <cassert> | ||
|
||
auto MY_PI = 3.14159265359; | ||
|
||
double EvaluateSinPlusLin(double A, double B, double C, double D, double x) | ||
{ | ||
/*When this equation is equal to zero, the distance between the point and the helix is the shortest.*/ | ||
return A * std::sin(x + B) + C * x + D; | ||
} | ||
|
||
double SolveSinPlusLin(double A, double B, double C, double D, double mi, double ma) | ||
{ | ||
/*Binary search to determine x, with which EvaluateSinPlusLin equation equals zero.*/ | ||
for (int i = 0; i < 100; i++) | ||
{ | ||
double mid = (mi + ma) / 2; | ||
double vmi = EvaluateSinPlusLin(A, B, C, D, mi); | ||
double vmid = EvaluateSinPlusLin(A, B, C, D, mid); | ||
double vma = EvaluateSinPlusLin(A, B, C, D, ma); | ||
|
||
if (vmi < 0 and 0 < vmid) | ||
{ | ||
ma = mid; | ||
} | ||
else if (vmid < 0 and 0 < vma) | ||
{ | ||
mi = mid; | ||
} | ||
else if (vmid < 0 and 0 < vmi) | ||
{ | ||
ma = mid; | ||
} | ||
else if (vma < 0 and 0 < vmid) | ||
{ | ||
mi = mid; | ||
} | ||
else | ||
{ | ||
break; | ||
mi = mid; | ||
} | ||
} | ||
|
||
double x = (mi + ma) / 2; | ||
return x; | ||
} | ||
|
||
double NextValPiK(double offs, double x) | ||
{ | ||
/*Find the next 2 * PI * k + offset (where k is an integer) that is greater than x.*/ | ||
|
||
if (x < 0) | ||
{ | ||
double v = -NextValPiK(-offs, -x) + 2 * MY_PI; | ||
return v > x ? v : v + 2 * MY_PI; | ||
} | ||
|
||
double kie = std::floor(x / 2 / MY_PI); | ||
|
||
for (int i = -2; i <= 2; i++) | ||
{ | ||
double v = (kie + i) * 2 * MY_PI + offs; | ||
|
||
if (v > x) | ||
{ | ||
return v; | ||
} | ||
} | ||
|
||
return 1000000000; | ||
} | ||
|
||
// A cos(x + B) + C = 0 | ||
double NextSinPlusInflection(double A, double B, double C, double x) | ||
{ | ||
/* Identifies the next inflection point of the sine curve.*/ | ||
// cos(x + B) = -C / A | ||
if (-C / A >= -1 && -C / A <= 1) | ||
{ | ||
double inv = std::acos(-C / A); | ||
return std::min(NextValPiK(inv - B, x), NextValPiK(-inv - B, x)); | ||
} | ||
else | ||
{ | ||
return 1000000000; | ||
} | ||
} |
Oops, something went wrong.