10#include <top/modules/OpticalGun/OpticalGunModule.h>
13#include <top/geometry/TOPGeometryPar.h>
16#include <framework/gearbox/Unit.h>
17#include <framework/logging/Logger.h>
21#include <Math/EulerAngles.h>
24#include <top/reconstruction_cpp/func.h>
27using namespace ROOT::Math;
60 addParam(
"na",
m_na,
"source numerical aperture. It is used only by the Gaussian distribution", 0.50);
62 "source angular distribution: uniform, Lambertian, an arbitrary TFormula, or Gaussian "
63 "(numerical aperture instead of minAlpha and maxAlpha). If you are writing a TFormula, "
64 "assume the angles are measured in degrees. The conversion to radians is done internally.",
67 addParam(
"phi",
m_phi,
"first rotation angle (around z) [deg]", 0.0);
68 addParam(
"theta",
m_theta,
"second rotation angle (around x) [deg]", 0.0);
69 addParam(
"psi",
m_psi,
"third rotation angle (around z) [deg]", 0.0);
71 "start time [ns]. If TOPCalPulseGenerator is in path this is relative to the first cal pulse", 0.0);
74 "average number of photons per pulse, if positive, otherwise exactly one", 0.0);
76 "TOP slot ID (1-16): if valid, source position and rotation angles assumed to be given in a local bar frame, "
77 "otherwise Belle II frame is assumed", 0);
78 addParam(
"slitDX",
m_slitDX,
"slit size in x [cm], if positive, otherwise full open", 0.0);
79 addParam(
"slitDY",
m_slitDY,
"slit size in y [cm], if positive, otherwise full open", 0.0);
80 addParam(
"slitX0",
m_slitX0,
"slit x-offset in respect to source [cm] ", 0.0);
81 addParam(
"slitY0",
m_slitY0,
"slit y-offset in respect to source [cm] ", 0.0);
82 addParam(
"slitZ",
m_slitZ,
"slit distance to source [cm], if > 0.01, otherwise slit full open", 0.0);
97 if (m_wavelength < 150 or m_wavelength > 1000)
98 B2FATAL(
"Wavelength does not correspond to optical photons.");
99 if (m_na < 0 or m_na > 1)
100 B2FATAL(
"Numerical aperture must be between 0 and 1.");
102 B2FATAL(
"Minimum emission angle must be positive");
104 B2FATAL(
"Maximum emission angle must be positive");
106 B2FATAL(
"Minimum emission angle must me smaller than the maximum emission angle");
114 <<
"Checking if it's a valid, positively-defined TFormula.");
116 int result = testFormula.Compile();
122 double value = testFormula.Eval(testPoint *
Unit::deg);
125 << testPoint <<
" deg (value = " << value <<
")");
142 if (not geo->isModuleIDValid(
m_slotID)) B2FATAL(
"Slot ID is not valid");
143 const auto& T = geo->getModule(
m_slotID).getTransformation();
163 for (
int i = 0; i < numPhotons; i++) {
171 XYZPoint point(x, y, 0);
184 XYZVector momentum =
m_energy * direction;
190 double alphaPol = 2.0 * M_PI * gRandom->Rndm();
191 XYZVector polarization(cos(alphaPol), sin(alphaPol), 0);
195 double emissionTime = gRandom->Gaus(startTime,
m_pulseWidth);
208 part->setProductionVertex(
static_cast<XYZVector
>(point));
209 part->setProductionTime(emissionTime);
210 part->setMomentum(momentum);
212 part->setDecayVertex(polarization);
219 const XYZVector& direction)
const
221 if (
m_slitZ < 0.01)
return true;
222 if (direction.Z() < 1.0e-6)
return false;
224 double pathLength = (
m_slitZ - point.Z()) / direction.Z();
226 double x = point.X() + pathLength * direction.X();
230 double y = point.Y() + pathLength * direction.Y();
245 x = gRandom->Gaus(0., asin(
m_na) / 2.45);
246 y = gRandom->Gaus(0., asin(
m_na) / 2.45);
247 z = 1. - x * x - y * y;
249 return XYZVector(x, y,
sqrt(z));
255 double sinTheta =
sqrt(1.0 - cosTheta * cosTheta);
256 double phi = 2.0 * M_PI * gRandom->Rndm();
257 return XYZVector(cos(phi) * sinTheta, sin(phi) * sinTheta, cosTheta);
264 double sinTheta =
sqrt(1.0 - cosTheta * cosTheta);
265 double phi = 2.0 * M_PI * gRandom->Rndm();
266 return XYZVector(cos(phi) * sinTheta, sin(phi) * sinTheta, cosTheta);
272 double phi = 2.0 * M_PI * gRandom->Rndm();
273 return XYZVector(cos(phi) * sin(alpha), sin(phi) * sin(alpha), cos(alpha));
@ c_PrimaryParticle
bit 0: Particle is primary particle.
@ c_StableInGenerator
bit 1: Particle is stable, i.e., not decaying in the generator.
void setPDG(int pdg)
Set PDG code of the particle.
void setDescription(const std::string &description)
Sets the description of the module.
void setPropertyFlags(unsigned int propertyFlags)
Sets the flags for the module properties.
@ c_ParallelProcessingCertified
This module can be run in parallel processing mode safely (All I/O must be done through the data stor...
std::string m_angularDistribution
source angular distribution
double m_minAlpha
minimum emission angle
TF1 * m_customDistribution
Custom angular distribution, that uses m_angularDistribution as formula.
double m_slitZ
slit distance from source
double m_cosMinAlpha
cos of m_minAlpha
StoreArray< TOPSimCalPulse > m_simCalPulses
simulated cal pulse collection
double m_slitDX
slit size in x
double m_wavelength
source wavelenght [nm]
double m_cosMaxAlpha
cos of m_maxAlpha
double m_slitDY
slit size in y
double m_slitX0
slit x-offset in respect to source
double m_na
source numerical aperture.
double m_slitY0
slit y-offset in respect to source
double m_phi
first rotation angle (around z) [deg]
double m_x
source position in x
double m_theta
second rotation angle (around x) [deg]
double m_startTime
start time
double m_maxAlpha
maximum emission angle
double m_energy
photon energy (from wavelength)
double m_diameter
source diameter
double m_psi
third rotation angle (around z) [deg]
double m_z
source position in z
double m_y
source position in y
double m_pulseWidth
pulse duration (Gaussian sigma)
double m_numPhotons
average number of photons in a pulse
StoreArray< MCParticle > m_MCParticles
MC particles collection.
ROOT::Math::Transform3D m_transform
transformation to BelleII frame
bool registerInDataStore(DataStore::EStoreFlags storeFlags=DataStore::c_WriteOut)
Register the object/array in the DataStore.
T * appendNew()
Construct a new T object at the end of the array.
const TOPGeometry * getGeometry() const
Returns pointer to geometry object using basf2 units.
static TOPGeometryPar * Instance()
Static method to obtain the pointer to its instance.
static const double c_hc
Planck constant times speed of light in [eV*nm].
static const double deg
degree to radians
static const double eV
[electronvolt]
void addParam(const std::string &name, T ¶mVariable, const std::string &description, const T &defaultValue)
Adds a new parameter to the module.
#define REG_MODULE(moduleName)
Register the given module (without 'Module' suffix) with the framework.
double sqrt(double a)
sqrt for double
ROOT::Math::XYZVector getDirectionGaussian() const
Return photon direction according to a projected 2D gaussian distribution based on numerical aperture...
virtual ~OpticalGunModule()
Destructor.
ROOT::Math::XYZVector getDirectionUniform() const
Return photon direction according to a projected uniform distribution with opening angle alpha.
ROOT::Math::XYZVector getDirectionCustom() const
Return photon direction according to a custom angular distribution given by TFormula.
virtual void initialize() override
Initialize the Module.
OpticalGunModule()
Constructor.
virtual void event() override
Event processor.
bool isInsideSlit(const ROOT::Math::XYZPoint &point, const ROOT::Math::XYZVector &direction) const
Checks if photon passes the slit.
ROOT::Math::XYZVector getDirectionLambertian() const
Return photon direction according to a lambertian distribution with opening angle alpha.
void rotateUz(ROOT::Math::XYZVector &vec, const ROOT::Math::XYZVector &z_Axis)
Replacement for a function TVector3::RotateUz which is not implemented in GenVector classes.
Abstract base class for different kinds of events.