Skip to content

Commit 9460468

Browse files
committed
Add integration test for drawing figures
1 parent dd2b749 commit 9460468

4 files changed

Lines changed: 414 additions & 0 deletions

File tree

AtTools/AtPropagator.cxx

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,21 @@ AtPropagator::XYZVector AtPropagator::d2xds2(const XYZPoint &pos, const XYZVecto
5858
return 1 / p * (dpds_vec - phat * (phat.Dot(dpds_vec))); // Second derivative of position w.r.t. arc length
5959
}
6060

61+
void AtPropagator::PropagateOneStep(AtStepper &stepper)
62+
{
63+
if (fState.h == 0)
64+
fState.h = stepper.GetInitialStep(); // Set the initial step size
65+
66+
stepper.fDeriv = [this](const XYZPoint &pos, const XYZVector &mom) { return this->Derivatives(pos, mom); };
67+
68+
auto result = stepper.Step(fState);
69+
if (!result) {
70+
LOG(error) << "Integration step failed, aborting propagation.";
71+
return; // Abort propagation if step failed
72+
}
73+
fState = result; // Update the internal state
74+
}
75+
6176
void AtPropagator::PropagateToMeasurementSurface(const AtMeasurementSurface &surface, AtStepper &stepper)
6277
{
6378
LOG(info) << "Propagating to measurement surface";

AtTools/AtPropagator.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,7 @@ class AtPropagator {
104104
fState.fPos = pos;
105105
fState.fMom = mom;
106106
}
107+
const StepState &GetState() const { return fState; }
107108

108109
XYZPoint GetPosition() const { return fState.fPos; }
109110
XYZVector GetMomentum() const { return fState.fMom; }
@@ -121,6 +122,14 @@ class AtPropagator {
121122

122123
void PropagateToMeasurementSurface(const AtMeasurementSurface &surface, AtStepper &stepper);
123124

125+
/**
126+
* @brief Propagate the particle using the given stepper.
127+
* Propagates one step using the provided stepper.
128+
*
129+
* @param stepper The stepper to use for propagation.
130+
*/
131+
void PropagateOneStep(AtStepper &stepper);
132+
124133
/**
125134
* @brief Calculate the force acting on the particle.
126135
*

macro/tests/UKF/AtPropagator.C

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
std::string getEnergyPath()
2+
{
3+
auto env = std::getenv("VMCWORKDIR");
4+
if (env == nullptr) {
5+
return "../../resources/energy_loss/HinH.txt"; // Default path assuming cwd is build/AtTools
6+
}
7+
return std::string(env) + "/resources/energy_loss/HinH.txt"; // Use environment variable
8+
}
9+
10+
const double mass_p = 938.272; // Mass of proton in MeV/c^2
11+
const double charge_p = 1.602176634e-19; // Charge of proton
12+
13+
// This test should plot the trajectory of a particle in a magnetic field using
14+
// the output from GEANT and the AtPropagator class.
15+
void AtPropagator()
16+
{
17+
using namespace AtTools;
18+
19+
std::vector<double> x, y, z;
20+
std::vector<double> x2, y2, z2;
21+
22+
std::ifstream infile("hits.txt");
23+
double xi, yi, zi, Ei;
24+
while (infile >> xi >> yi >> zi >> Ei) {
25+
x.push_back(xi * 10);
26+
y.push_back(yi * 10);
27+
z.push_back(zi * 10);
28+
}
29+
30+
// Our propagator setup
31+
double charge = charge_p; // Charge in Coulombs
32+
double mass = mass_p; // Mass in MeV/c^2
33+
auto elossModel = std::make_unique<AtTools::AtELossTable>(0);
34+
elossModel->LoadSrimTable(getEnergyPath()); // Use the function to get the path
35+
elossModel->SetDensity(3.553e-5); // Set density in g/cm^3 for 300 torr H2
36+
AtTools::AtPropagator propagator(charge, mass, std::move(elossModel));
37+
propagator.SetEField({0, 0, 0}); // No electric field
38+
propagator.SetBField({0, 0, 2.85}); // Magnetic field
39+
AtTools::AtRK4Stepper stepper;
40+
41+
XYZPoint startPos(-3.40046e-05, -1.49863e-05, 0.10018); // Start position in cm
42+
startPos *= 10; // Convert to mm
43+
XYZVector startMom(0.00935463, -0.0454279, 0.00826042); // Start momentum in GeV/c
44+
startMom *= 1e3; // Convert to MeV/c
45+
46+
propagator.SetState(startPos, startMom);
47+
48+
// Loop through until the particle is stopped
49+
while (Kinematics::KE(propagator.GetState().fMom, propagator.GetState().fMass) > 0.1) {
50+
// Propagate to the next point
51+
propagator.PropagateOneStep(stepper);
52+
53+
// Get the current position and momentum
54+
auto pos = propagator.GetPosition();
55+
56+
// Store the position for plotting
57+
x2.push_back(pos.X());
58+
y2.push_back(pos.Y());
59+
z2.push_back(pos.Z());
60+
}
61+
62+
TGraph2D *track = new TGraph2D(x.size(), x.data(), y.data(), z.data());
63+
track->SetTitle("Particle Track;X [mm];Y [mm];Z [mm]");
64+
track->SetMarkerStyle(20);
65+
track->SetMarkerSize(0.8);
66+
67+
TGraph2D *track2 = new TGraph2D(x2.size(), x2.data(), y2.data(), z2.data());
68+
track2->SetTitle("Propagated Particle Track;X [mm];Y [mm];Z [mm]");
69+
track2->SetMarkerStyle(21);
70+
track2->SetMarkerSize(0.8);
71+
track2->SetMarkerColor(kRed);
72+
73+
TCanvas *c1 = new TCanvas("c1", "Particle Track", 800, 600);
74+
track->Draw("P");
75+
track2->Draw("PSAME");
76+
}

0 commit comments

Comments
 (0)