OPAL (Object Oriented Parallel Accelerator Library)  2024.1
OPAL
Probe.cpp
Go to the documentation of this file.
1 //
2 // Class Probe
3 // Interface for a probe
4 //
5 // Copyright (c) 2016-2020, Paul Scherrer Institut, Villigen PSI, Switzerland
6 // All rights reserved
7 //
8 // This file is part of OPAL.
9 //
10 // OPAL is free software: you can redistribute it and/or modify
11 // it under the terms of the GNU General Public License as published by
12 // the Free Software Foundation, either version 3 of the License, or
13 // (at your option) any later version.
14 //
15 // You should have received a copy of the GNU General Public License
16 // along with OPAL. If not, see <https://www.gnu.org/licenses/>.
17 //
18 #include "AbsBeamline/Probe.h"
19 
22 #include "Physics/Physics.h"
23 #include "Physics/Units.h"
24 #include "Structure/LossDataSink.h"
25 #include "Structure/PeakFinder.h"
26 
27 extern Inform *gmsg;
28 
30 {}
31 
32 Probe::Probe(const std::string &name):
33  PluginElement(name),
34  step_m(0.0)
35 {}
36 
37 Probe::Probe(const Probe &right):
38  PluginElement(right),
39  step_m(right.step_m)
40 {}
41 
43 
44 void Probe::accept(BeamlineVisitor &visitor) const {
45  visitor.visitProbe(*this);
46 }
47 
49  bool singlemode = (bunch->getTotalNum() == 1) ? true : false;
50  peakfinder_m = std::unique_ptr<PeakFinder> (new PeakFinder(getOutputFN(), rmin_m, rend_m, step_m, singlemode));
51 }
52 
54  *gmsg << "* Probe " << getName() << " goes offline" << endl;
55  if (online_m && peakfinder_m)
56  peakfinder_m->save();
57  peakfinder_m.reset(nullptr);
58 }
59 
60 void Probe::setStep(double step) {
61  step_m = step;
62 }
63 
64 double Probe::getStep() const {
65  return step_m;
66 }
67 
69  Vector_t rmin, rmax;
70  bunch->get_bounds(rmin, rmax);
71  // interested in absolute minimum and maximum
72  double xmin = std::min(std::abs(rmin(0)), std::abs(rmax(0)));
73  double xmax = std::max(std::abs(rmin(0)), std::abs(rmax(0)));
74  double ymin = std::min(std::abs(rmin(1)), std::abs(rmax(1)));
75  double ymax = std::max(std::abs(rmin(1)), std::abs(rmax(1)));
76  double rbunch_min = std::hypot(xmin, ymin);
77  double rbunch_max = std::hypot(xmax, ymax);
78 
79  if (rbunch_max > rmin_m - 0.01 && rbunch_min < rend_m + 0.01 ) {
80  return true;
81  }
82  return false;
83 }
84 
85 bool Probe::doCheck(PartBunchBase<double, 3> *bunch, const int turnnumber, const double t, const double tstep) {
86  Vector_t probepoint;
87  size_t tempnum = bunch->getLocalNum();
88 
89  for (unsigned int i = 0; i < tempnum; ++i) {
90  double tangle = calculateIncidentAngle(bunch->P[i](0), bunch->P[i](1));
91  changeWidth(bunch, i, tstep, tangle);
92  int pflag = checkPoint(bunch->R[i](0), bunch->R[i](1));
93  if (pflag == 0) continue;
94  // calculate closest point at probe -> better to use momentum direction
95  // probe: y = -A/B * x - C/B or A*X + B*Y + C = 0
96  // perpendicular line through R: y = B/A * x + R(1) - B/A * R(0)
97  // probepoint(0) = (B_m*B_m*bunch->R[i](0) - A_m*B_m*bunch->R[i](1) - A_m*C_m) / (R_m*R_m);
98  // probepoint(1) = (A_m*A_m*bunch->R[i](1) - A_m*B_m*bunch->R[i](0) - B_m*C_m) / (R_m*R_m);
99  // probepoint(2) = bunch->R[i](2);
100  // calculate time correction for probepoint
101  // dist1 > 0, right hand, dt > 0; dist1 < 0, left hand, dt < 0
102  double dist1 = (A_m * bunch->R[i](0) + B_m * bunch->R[i](1) + C_m) / R_m; // [m]
103  double dist2 = dist1 * std::sqrt(1.0 + 1.0 / tangle / tangle);
104  double dt = dist2 / (std::sqrt(1.0 - 1.0 / (1.0 + dot(bunch->P[i], bunch->P[i]))) * Physics::c);
105 
106  probepoint = bunch->R[i] + dist2 * bunch->P[i] / euclidean_norm(bunch->P[i]);
107 
108  // peak finder uses millimetre not metre
109  peakfinder_m->addParticle(probepoint * Units::m2mm);
110 
111  lossDs_m->addParticle(OpalParticle(bunch->ID[i], probepoint, bunch->P[i],
112  t+dt, bunch->Q[i], bunch->M[i]),
113  std::make_pair(turnnumber, bunch->bunchNum[i]));
114  }
115 
116  peakfinder_m->evaluate(turnnumber);
117 
118  // we do not lose particles in the probe
119  return false;
120 }
121 
123  return ElementType::PROBE;
124 }
Tps< T > sqrt(const Tps< T > &x)
Square root.
Definition: TpsMath.h:91
constexpr double c
The velocity of light in m/s.
Definition: Physics.h:45
virtual bool doCheck(PartBunchBase< double, 3 > *bunch, const int turnnumber, const double t, const double tstep) override
Record probe hits when bunch particles pass.
Definition: Probe.cpp:85
double step_m
Step size of the probe (bin width in histogram file)
Definition: Probe.h:59
constexpr double m2mm
Definition: Units.h:26
PETE_TUTree< FnAbs, typename T::PETE_Expr_t > abs(const PETE_Expr< T > &l)
ParticleAttrib< Vector_t > P
ParticleAttrib< short > bunchNum
void get_bounds(Vector_t &rmin, Vector_t &rmax) const
ParticleAttrib< double > M
virtual ~Probe()
Definition: Probe.cpp:42
virtual void doInitialise(PartBunchBase< double, 3 > *bunch) override
Initialise peakfinder file.
Definition: Probe.cpp:48
virtual const std::string & getName() const
Get element name.
Inform & endl(Inform &inf)
Definition: Inform.cpp:42
std::unique_ptr< LossDataSink > lossDs_m
Pointer to Loss instance.
Probe()
Definition: Probe.cpp:29
T::PETE_Expr_t::PETE_Return_t min(const PETE_Expr< T > &expr, NDIndex< D > &loc)
Definition: ReductionLoc.h:76
T::PETE_Expr_t::PETE_Return_t max(const PETE_Expr< T > &expr, NDIndex< D > &loc)
Definition: ReductionLoc.h:84
double rmin_m
radius closest to the origin
virtual bool doPreCheck(PartBunchBase< double, 3 > *) override
Virtual hook for preCheck.
Definition: Probe.cpp:68
T euclidean_norm(const Vector< T > &)
Euclidean norm.
Definition: Vector.h:243
size_t getTotalNum() const
virtual double getStep() const
Member variable access.
Definition: Probe.cpp:64
int checkPoint(const double &x, const double &y) const
Checks if coordinate is within element.
bool online_m
Definition: Component.h:192
size_t getLocalNum() const
Definition: Inform.h:42
ElementType
Definition: ElementBase.h:88
ParticleAttrib< double > Q
std::unique_ptr< PeakFinder > peakfinder_m
Pointer to Peakfinder instance.
Definition: Probe.h:60
double calculateIncidentAngle(double xp, double yp) const
Calculate angle of particle/bunch wrt to element.
void changeWidth(PartBunchBase< double, 3 > *bunch, int i, const double tstep, const double tangle)
Change probe width depending on step size and angle of particle.
const std::string name
ParticlePos_t & R
void setStep(double step)
Set probe histogram bin width.
Definition: Probe.cpp:60
ParticleIndex_t & ID
double C_m
Geometric lengths used in calculations.
Definition: Probe.h:28
virtual void doGoOffline() override
Hook for goOffline.
Definition: Probe.cpp:53
virtual void accept(BeamlineVisitor &) const override
Apply visitor to Probe.
Definition: Probe.cpp:44
virtual void visitProbe(const Probe &)=0
Apply the algorithm to a probe.
std::string getOutputFN() const
Get output filename.
virtual ElementType getType() const override
Get element type std::string.
Definition: Probe.cpp:122
Inform * gmsg
Definition: Main.cpp:70
double dot(const Vector3D &lhs, const Vector3D &rhs)
Vector dot product.
Definition: Vector3D.cpp:118