9 #include <top/reconstruction_cpp/YScanner.h>
10 #include <top/reconstruction_cpp/func.h>
11 #include <top/geometry/TOPGeometryPar.h>
12 #include <framework/logging/Logger.h>
29 if (sol_dx.
step == 0) B2ERROR(
"TOP::YScanner::Derivatives: step (dx) is zero");
30 if (sol_de.
step == 0) B2ERROR(
"TOP::YScanner::Derivatives: step (de) is zero");
31 if (sol_dL.
step == 0) B2ERROR(
"TOP::YScanner::Derivatives: step (dL) is zero");
53 B2FATAL(
"TOP::YScanner: N must be > 1");
60 const auto* geo = topgp->getGeometry();
61 auto qe = geo->getNominalQE();
62 qe.applyFilterTransmission(geo->getWavelengthFilter());
67 B2FATAL(
"TOP::YScanner: quantum efficiency found zero for all wavelengths");
72 const auto& tdc = geo->getNominalTDC();
73 for (
unsigned i = 0; i < N; i++) {
76 double effi = qe.getEfficiency(lambda) * tdc.getEfficiency();
87 double p = entry.y * (1 - 1 / pow(topgp->getPhaseIndex(e), 2));
129 if (beta * topgp->getPhaseIndex(
m_meanE0) < 1)
return;
134 if (area == 0)
return;
142 const double radLength = 12.3;
143 double thetaScat = 13.6e-3 / beta / momentum *
sqrt(length / 2 / radLength);
145 double n = topgp->getPhaseIndex(
m_meanE);
147 B2ERROR(
"TOP::YScanner::prepare: beta * n < 1 ==> must be a bug!");
150 double dndE = topgp->getPhaseIndexDerivative(
m_meanE);
151 double dEdTheta = n *
sqrt(pow(beta * n, 2) - 1) / dndE;
174 double p = std::max(entry.y * (1 - 1 / pow(beta * topgp->getPhaseIndex(e), 2)), 0.0);
175 double ee = entry.xsq;
181 if (s == 0)
return 0;
196 B2ERROR(
"TOP::YScanner:setQuasyEnergyDistribution: unexpectedly large size of the std::map found, map cleared");
200 int ng = lround(3 * sigma / step);
203 if (quasyEnergyDistribution.entries.empty()) {
204 std::vector<double> gaus;
205 for (
int i = 0; i <= ng; i++) {
206 double x = step * i / sigma;
207 gaus.push_back(exp(-0.5 * x * x));
213 for (
int k = -ng; k < N + ng; k++) {
217 for (
int i = -ng; i <= ng; i++) {
228 quasyEnergyDistribution.entries.push_back(
TableEntry(s, se, see));
231 for (
auto& entry : quasyEnergyDistribution.entries) entry.y /= sum;
242 if (D.dyB_de == 0)
return;
250 double dely = (std::abs(D.dyB_dL) *
m_length + std::abs(D.dyB_dx) * pixDx) / 2;
251 double y1 = yB - dely;
252 double y2 = yB + dely;
254 y1 += D.dyB_de * (minE -
m_meanE);
255 y2 += D.dyB_de * (maxE -
m_meanE);
257 y1 += D.dyB_de * (maxE -
m_meanE);
258 y2 += D.dyB_de * (minE -
m_meanE);
260 double B =
m_bars.front().B;
261 int j1 = lround(y1 / B);
262 int j2 = lround(y2 / B) + 1;
265 scan(col, yB, dydz, D, j1, j2);
268 merge(col, dydz, j1, j2);
277 std::map<int, EnergyMask*> masks;
284 std::vector<PixelProjection> projections[2];
288 if (proj.
Dy > 0) projections[0].push_back(proj);
291 if (proj.
Dy > 0) projections[1].push_back(proj);
293 if (projections[0].empty() and projections[1].empty())
continue;
295 for (
unsigned k = 0; k < 2; k++) {
296 std::sort(projections[k].begin(), projections[k].end());
297 for (
auto& projection : projections[k]) {
298 int iDy = lround(projection.Dy * 1000);
299 auto& mask = masks[iDy];
301 double Dy = projection.Dy;
305 projection.mask = mask;
310 double wid_old = 1000;
312 for (
int j = j1; j < j2; j++) {
313 double ybar = j *
m_bars.front().B - yB;
314 for (
const auto& projection : projections[std::abs(j) % 2]) {
315 double Ecp = (ybar + projection.yc) / D.dyB_de +
m_meanE;
316 double wid = projection.mask->getFullWidth();
317 if (std::abs(Ecp - Ecp_old) > (wid + wid_old) / 2 and
m_results.back().sum > 0) {
329 for (
auto& result :
m_results) result.set();
331 for (
auto& mask : masks) {
332 if (mask.second)
delete mask.second;
341 int Nodd = j2 - j1 - Neven;
354 if (proj.
Dy > 0) Dy0 += proj.
Dy;
356 if (proj.
Dy > 0) Dy1 += proj.
Dy;
358 if (Dy0 == 0 and Dy1 == 0)
continue;
360 double Dy = (Dy0 * Neven + Dy1 * Nodd) / (Neven + Nodd);
362 result.sum = Dy /
m_bars.front().B;
372 const auto& mask = energyMask->
getMask();
378 double m = energyMask->
getMask(
E - Ecp);
381 double s = entry.y * m;
383 result.e0 += entry.x * s;
384 result.sigsq += entry.xsq * s;
396 int M = mask.size() - 1;
397 int i1 = std::max(i0 - M, 0);
398 int i2 = std::min(i0 + M - 1, N);
399 for (
int i = i1; i <= i2; i++) {
401 double m = mask[std::abs(i - i0)] * (1 - fract) + mask[std::abs(i - i0 + 1)] * fract;
402 double s = entry.y * m;
404 result.e0 += entry.x * s;
405 result.sigsq += entry.xsq * s;
415 double z1 = y * win.sz + win.z0 + win.nz * dz;
416 double y1 = y * win.sy + win.y0 + win.ny * dz;
423 double halfSize = (k -
m_prism.
k0) % 2 == 0 ? size / 2 : -size / 2;
427 double Bh =
m_bars.front().B / 2;
428 y1 = std::max(y1, -Bh);
429 y2 = std::min(y2, Bh);
431 proj.
yc = (y1 + y2) / 2;
A mask for energy masking.
const std::vector< double > & getMask() const
Returns discrete mask (note: only half of the mask is stored)
Pixel relative efficiencies of a single module.
Pixel masks of a single module.
bool isActive(int pixelID) const
Checks if pixel is active.
Pixel positions and dimensions in module local frame.
int pixelID(unsigned row, unsigned col) const
Transforms pixel row and column to pixel ID Note: for convenience pixel row and column numbering star...
unsigned getNumPixelRows() const
Returns the number of pixel rows.
const PixelData & get(int pixelID) const
Returns pixel data for given pixelID.
Base class with geometry data.
@ c_Unified
single bar with average width and thickness
@ c_SemiLinear
semi-linear approximation
Prism m_prism
prism geometry data
std::vector< BarSegment > m_bars
geometry data of bar segments
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].
double m_cosTotal
cosine of total reflection angle
void prepare(double momentum, double beta, double length) const
Prepare for the PDF expansion in y for a given track mass hypothesis.
Table m_energyDistribution
photon energy distribution
PixelEfficiencies m_pixelEfficiencies
pixel relative efficiencies
double m_beta
particle beta
bool m_scanDone
true if scan performed, false if reflections just merged
void projectPixel(double yc, double size, int k, double dydz, PixelProjection &proj) const
Calculates a projection of a pixel to prism entrance window (going down-stream the photon).
Table m_efficiency
nominal photon detection efficiencies (PDE)
double m_meanE
mean photon energy
static int s_maxReflections
maximal number of reflections to perform scan
double m_rmsE
r.m.s of photon energy
bool m_aboveThreshold
true if beta is above the Cerenkov threshold
void merge(unsigned col, double dydz, int j1, int j2) const
Performs expansion by merging all reflections.
void scan(unsigned col, double yB, double dydz, const Derivatives &D, int j1, int j2) const
Performs expansion w/ the scan over reflections.
double m_meanE0
mean photon energy for beta = 1
double m_momentum
particle momentum magnitude
Table * m_quasyEnergyDistribution
a pointer to the element in m_quasyEnergyDistributions
PixelMasks m_pixelMasks
pixel masks
void setQuasyEnergyDistribution(double sigma) const
Sets photon energy distribution convoluted with a normalized Gaussian.
void integrate(const EnergyMask *energyMask, double Ecp, Result &result) const
Integrates quasy energy distribution multiplied with energy mask.
void expand(unsigned col, double yB, double dydz, const Derivatives &D, int Ny, bool doScan) const
Performs the PDF expansion in y for a given pixel column using scan or merge methods.
YScanner(int moduleID, unsigned N=64)
Class constructor.
std::map< int, Table > m_quasyEnergyDistributions
photon energy distributions convoluted with Gaussian of different widths
double prismEntranceY(double y, int k, double dydz) const
Calculates y at prism entrance from detection position, reflection number and photon slope.
double setEnergyDistribution(double beta) const
Sets photon energy distribution and mean photon energy according to nominal PDE and particle beta.
double m_length
length of particle trajectory inside quartz
double m_rmsE0
r.m.s of photon energy for beta = 1
std::vector< Result > m_results
results of PDF expansion in y
PixelPositions m_pixelPositions
positions and sizes of pixels
void clear() const
Clear mutable variables.
double m_numPhotons
number of photons per Cerenkov azimuthal angle per track length
double m_sigmaAlpha
surface roughness parameter in photon energy units
double sqrt(double a)
sqrt for double
int getNumOfEven(int j1, int j2)
Returns number of even numbers in the range given by arguments.
Abstract base class for different kinds of events.
Solution of inverse ray-tracing.
double step
step for numerical derivative calculation
std::vector< TOPGeoPrism::UnfoldedWindow > unfoldedWindows
unfolded prism exit windows
double zFlat
z where flat continues to slanted surface
double zR
maximal z, i.e position of prism-bar joint
double zD
detector (photo-cathode) position
int k0
index of true prism in the vector 'unfoldedWindows'
static double dyB_d(const InverseRaytracer::Solution &sol0, const InverseRaytracer::Solution &sol1)
Calculates the derivative of unfolded y coordinate at prism entrance.
static double dLen_d(const InverseRaytracer::Solution &sol0, const InverseRaytracer::Solution &sol1)
Calculates the derivative of propagation length.
double dFic_de
Cerenkov azimuthal angle over photon energy.
double dLen_de
propagation length over photon energy
Derivatives()
Default constructor.
double dFic_dx
Cerenkov azimuthal angle over photon detection coordinate x.
double dFic_dL
Cerenkov azimuthal angle over running parameter of particle trajectory.
double dLen_dL
propagation length over running parameter of particle trajectory
double dyB_de
unfolded y coordinate at prism entrance over photon energy
double dLen_dx
propagation length over photon detection coordinate x
double dyB_dL
unfolded y coordinate at prism entrance over running parameter of particle trajectory
double dyB_dx
unfolded y coordinate at prism entrance over photon detection coordinate x
static double dFic_d(const InverseRaytracer::Solution &sol0, const InverseRaytracer::Solution &sol1)
Calculates the derivative of Cerenkov azimuthal angle.
Down-stream projection of a pixel to prism entrance window w/ a clip on bar exit thickness.
double yc
center in y of clipped pixel projection
double Dy
size in y of clipped pixel projection
double getY(int i) const
Returns y for a given index.
int getIndex(double x) const
Returns index.
std::vector< TableEntry > entries
table entries
double getXmax() const
Returns x of the last entry.
double getX(int i) const
Returns x for a given index.
void clear()
Clear the content entirely.
double getXmin() const
Returns x of the first entry.
void set(double X0, double Step)
Sets the first x and the step, and clears the entries.