OPAL (Object Oriented Parallel Accelerator Library)  2021.1.99
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 "Structure/LossDataSink.h"
24 #include "Structure/PeakFinder.h"
25 
26 extern Inform *gmsg;
27 
29 {}
30 
31 Probe::Probe(const std::string &name):
33  step_m(0.0)
34 {}
35 
36 Probe::Probe(const Probe &right):
37  PluginElement(right),
38  step_m(right.step_m)
39 {}
40 
42 
43 void Probe::accept(BeamlineVisitor &visitor) const {
44  visitor.visitProbe(*this);
45 }
46 
48  bool singlemode = (bunch->getTotalNum() == 1) ? true : false;
49  peakfinder_m = std::unique_ptr<PeakFinder> (new PeakFinder(getOutputFN(), rmin_m, rend_m, step_m, singlemode));
50 }
51 
53  *gmsg << "* Probe goes offline " << getName() << endl;
54  if (online_m && peakfinder_m)
55  peakfinder_m->save();
56  peakfinder_m.reset(nullptr);
57 }
58 
59 void Probe::setStep(double step) {
60  step_m = step;
61 }
62 
63 double Probe::getStep() const {
64  return step_m;
65 }
66 
68  Vector_t rmin, rmax;
69  bunch->get_bounds(rmin, rmax);
70  // interested in absolute minimum and maximum
71  double xmin = std::min(std::abs(rmin(0)), std::abs(rmax(0)));
72  double xmax = std::max(std::abs(rmin(0)), std::abs(rmax(0)));
73  double ymin = std::min(std::abs(rmin(1)), std::abs(rmax(1)));
74  double ymax = std::max(std::abs(rmin(1)), std::abs(rmax(1)));
75  double rbunch_min = std::hypot(xmin, ymin);
76  double rbunch_max = std::hypot(xmax, ymax);
77 
78  if (rbunch_max > rmin_m - 0.01 && rbunch_min < rend_m + 0.01 ) {
79  return true;
80  }
81  return false;
82 }
83 
84 bool Probe::doCheck(PartBunchBase<double, 3> *bunch, const int turnnumber, const double t, const double tstep) {
85  Vector_t probepoint;
86  size_t tempnum = bunch->getLocalNum();
87 
88  for (unsigned int i = 0; i < tempnum; ++i) {
89  double tangle = calculateIncidentAngle(bunch->P[i](0), bunch->P[i](1));
90  changeWidth(bunch, i, tstep, tangle);
91  int pflag = checkPoint(bunch->R[i](0), bunch->R[i](1));
92  if (pflag == 0) continue;
93  // calculate closest point at probe -> better to use momentum direction
94  // probe: y = -A/B * x - C/B or A*X + B*Y + C = 0
95  // perpendicular line through R: y = B/A * x + R(1) - B/A * R(0)
96  // 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);
97  // 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);
98  // probepoint(2) = bunch->R[i](2);
99  // calculate time correction for probepoint
100  // dist1 > 0, right hand, dt > 0; dist1 < 0, left hand, dt < 0
101  double dist1 = (A_m * bunch->R[i](0) + B_m * bunch->R[i](1) + C_m) / R_m; // [m]
102  double dist2 = dist1 * std::sqrt(1.0 + 1.0 / tangle / tangle);
103  double dt = dist2 / (std::sqrt(1.0 - 1.0 / (1.0 + dot(bunch->P[i], bunch->P[i]))) * Physics::c);
104 
105  probepoint = bunch->R[i] + dist2 * bunch->P[i] / euclidean_norm(bunch->P[i]);
106 
107  // peak finder uses millimetre not metre
108  peakfinder_m->addParticle(probepoint * 1e3);
109 
110  lossDs_m->addParticle(OpalParticle(bunch->ID[i], probepoint, bunch->P[i],
111  t+dt, bunch->Q[i], bunch->M[i]),
112  std::make_pair(turnnumber, bunch->bunchNum[i]));
113  }
114 
115  peakfinder_m->evaluate(turnnumber);
116 
117  // we do not lose particles in the probe
118  return false;
119 }
120 
122  return PROBE;
123 }
Inform * gmsg
Definition: Main.cpp:62
Tps< T > sqrt(const Tps< T > &x)
Square root.
Definition: TpsMath.h:91
T euclidean_norm(const Vector< T > &)
Euclidean norm.
Definition: Vector.h:243
double dot(const Vector3D &lhs, const Vector3D &rhs)
Vector dot product.
Definition: Vector3D.cpp:118
T::PETE_Expr_t::PETE_Return_t max(const PETE_Expr< T > &expr, NDIndex< D > &loc)
Definition: ReductionLoc.h:84
T::PETE_Expr_t::PETE_Return_t min(const PETE_Expr< T > &expr, NDIndex< D > &loc)
Definition: ReductionLoc.h:76
PETE_TUTree< FnAbs, typename T::PETE_Expr_t > abs(const PETE_Expr< T > &l)
Inform & endl(Inform &inf)
Definition: Inform.cpp:42
const std::string name
constexpr double c
The velocity of light in m/s.
Definition: Physics.h:51
ParticlePos_t & R
size_t getLocalNum() const
ParticleAttrib< double > M
size_t getTotalNum() const
ParticleAttrib< Vector_t > P
ParticleAttrib< double > Q
void get_bounds(Vector_t &rmin, Vector_t &rmax)
ParticleAttrib< short > bunchNum
ParticleIndex_t & ID
virtual void visitProbe(const Probe &)=0
Apply the algorithm to a probe.
bool online_m
Definition: Component.h:195
virtual const std::string & getName() const
Get element name.
std::string getOutputFN() const
Get output filename.
int checkPoint(const double &x, const double &y) const
Checks if coordinate is within element.
double C_m
Geometric lengths used in calculations.
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.
double calculateIncidentAngle(double xp, double yp) const
Calculate angle of particle/bunch wrt to element.
std::unique_ptr< LossDataSink > lossDs_m
Pointer to Loss instance.
double rmin_m
radius closest to the origin
Definition: Probe.h:28
void setStep(double step)
Set probe histogram bin width.
Definition: Probe.cpp:59
virtual ~Probe()
Definition: Probe.cpp:41
std::unique_ptr< PeakFinder > peakfinder_m
Pointer to Peakfinder instance.
Definition: Probe.h:60
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:84
virtual ElementBase::ElementType getType() const override
Get element type std::string.
Definition: Probe.cpp:121
virtual void doInitialise(PartBunchBase< double, 3 > *bunch) override
Initialise peakfinder file.
Definition: Probe.cpp:47
double step_m
Step size of the probe (bin width in histogram file)
Definition: Probe.h:59
Probe()
Definition: Probe.cpp:28
virtual void doGoOffline() override
Hook for goOffline.
Definition: Probe.cpp:52
virtual bool doPreCheck(PartBunchBase< double, 3 > *) override
Virtual hook for preCheck.
Definition: Probe.cpp:67
virtual double getStep() const
Member variable access.
Definition: Probe.cpp:63
virtual void accept(BeamlineVisitor &) const override
Apply visitor to Probe.
Definition: Probe.cpp:43
Definition: Inform.h:42