1#ifndef __JDETECTOR__JPMTANALOGUESIGNALPROCESSOR__
2#define __JDETECTOR__JPMTANALOGUESIGNALPROCESSOR__
98 x1(
std::numeric_limits<double>::max())
117 static const int N = 100;
118 static const double precision = 1.0e-4;
145 const double Q = b*b - 4.0*a*c;
165 x1 = std::numeric_limits<double>::max();
170 for (
int i = 0; i != N; ++i) {
172 const double x = 0.5 * (xmin + xmax);
175 if (fabs(1.0 - u) < precision) {
185 x1 = 0.5 * (xmin + xmax);
247 return exp(-0.5*x*x);
299 if (th > 0.0 && th < 1.0)
302 THROW(
JValueOutOfRange,
"JPMTAnalogueSignalProcessor::getMaximalRiseTime(): Invalid threshold " << th);
329 return std::numeric_limits<double>::max();
353 return ((
double) NPE) *
gain;
538 }
else if (tot <= TOT) {
559 return gRandom->Rndm() <
QE;
576 return gRandom->Gaus(t_ns,
TTS_ns);
649 const double mu =
getGain(NPE);
652 q = gRandom->Gaus(mu, sigma);
675 const double X = gRandom->Uniform();
680 for (; k <= NPE; ++k) {
683 if (sum_p > X) {
break; }
692 q = gRandom->Gaus(mu, sigma);
715 q = gRandom->Gaus(mu, sigma);
766 const double mu =
getGain(NPE);
773 const double prob = gauss.getValue(npe);
776 const double normUpperLimit = std::numeric_limits<double>::infinity();
777 const double norm = gauss.getIntegral(normLowerLimit, normUpperLimit);
781 }
else if (std::fabs(npe - mu) <= 0.0001 * mu) {
806 for (
int k = 0; k <= NPE; ++k) {
815 prob += weight * gauss.getValue(npe);
818 const double normUpperLimit = std::numeric_limits<double>::infinity();
820 norm += weight * gauss.getIntegral(normLowerLimit, normUpperLimit);
822 }
else if (std::fabs(npe - mu) <= 0.0001 * mu) {
856 const double prob = gauss.getValue(npe);
859 const double normUpperLimit = std::numeric_limits<double>::infinity();
860 const double norm = gauss.getIntegral(normLowerLimit, normUpperLimit);
889 if (zmin < th) { zmin = th; }
890 if (zmax < th) { zmax = th; }
925 const double mu =
getGain(NPE);
932 const double cumulP = gauss.getIntegral(xmin, xmax);
935 const double normUpperLimit = std::numeric_limits<double>::infinity();
936 const double norm = gauss.getIntegral(normLowerLimit, normUpperLimit);
938 return cumulP / norm;
940 }
else if ((mu >= xmin) && (mu <= xmax)) {
966 for (
int k = 0; k <= NPE; ++k) {
976 const double normUpperLimit = std::numeric_limits<double>::infinity();
978 cumulP += weight * gauss.getIntegral(xmin, xmax);
979 norm += weight * gauss.getIntegral(normLowerLimit, normUpperLimit);
981 }
else if ((mu >= xmin) && (mu <= xmax)) {
994 return cumulP / norm;
1016 const double cumulP = gauss.getIntegral(xmin, xmax);
1019 const double normUpperLimit = std::numeric_limits<double>::infinity();
1020 const double norm = gauss.getIntegral(normLowerLimit, normUpperLimit);
1022 return cumulP / norm;
1141 THROW(
JValueOutOfRange,
"JPMTAnalogueSignalProcessor::getTimeOverThreshold: Invalid charge " << npe);
1169 y += npe / (2.0 * z);
1210 }
else if (
QE < 1.0) {
1214 for (
int i = 1; i <= NPE; ++i) {
1275 const double mu =
getGain(NPE);
1283 const double probUpperLimit = std::numeric_limits<double>::infinity();
1284 const double cumulP = gauss.getIntegral(probLowerLimit, probUpperLimit);
1286 const double normLowerLimit = 0.0;
1287 const double normUpperLimit = std::numeric_limits<double>::infinity();
1288 const double norm = gauss.getIntegral(normLowerLimit, normUpperLimit);
1290 return cumulP / norm;
1311 double cumulP = 0.0;
1315 for (
int k = 0; k <= NPE; ++k) {
1325 const double probUpperLimit = std::numeric_limits<double>::infinity();
1327 cumulP += weight * gauss.getIntegral(probLowerLimit, probUpperLimit);
1329 const double normLowerLimit = 0.0;
1330 const double normUpperLimit = std::numeric_limits<double>::infinity();
1332 norm += weight * gauss.getIntegral(normLowerLimit, normUpperLimit);
1347 return cumulP / norm;
1367 const double probUpperLimit = std::numeric_limits<double>::infinity();
1368 const double cumulP = gauss.getIntegral(probLowerLimit, probUpperLimit);
1370 const double normLowerLimit = 0.0;
1371 const double normUpperLimit = std::numeric_limits<double>::infinity();
1372 const double norm = gauss.getIntegral(normLowerLimit, normUpperLimit);
1374 return cumulP / norm;
1389 virtual double getNPE(
const double tot_ns)
const override
1392 return std::numeric_limits<double>::max();
1409 const double z = (-b + sqrt(b*b - 4*a*c)) / (2*a);
1434 const double npe =
getNPE(tot_ns);
1437 const double RaboveTh = y * v;
1441 const double gaussProb = gauss.getValue(tot_ns);
1442 const double gaussNorm = gauss.getIntegral(0,
saturation);
1443 const double gaussDist = gaussProb / gaussNorm;
1444 const double RthBand = (1-w) * gaussDist;
1446 return RaboveTh + RthBand;
1475 const double gaussCumulP = gauss.getIntegral(Xmin, Xmax);
1476 const double gaussNorm = gauss.getIntegral(0,
saturation);
1477 const double gaussDist = gaussCumulP / gaussNorm;
1478 const double IthBand = (1-w) * gaussDist;
1480 return IaboveTh + IthBand;
1531 const double precision = 1.0e-4)
1533 int i = (int) (NPE - 5.0 * sqrt(NPE));
1539 double p = NPE * exp(-NPE) / (double) 1;
1541 for (
int __i = 1; __i != i; ++__i) {
1547 for (
double p0 = 0.0; (p >= p0 || p > precision); ++i, p0 = p, p *= NPE / (double) i) {
1565 const double tot_ns,
1567 const double precision = 1.0e-4)
1569 int i = (int) (NPE - 5.0 * sqrt(NPE) - 0.5);
1570 int M = (int) (NPE + 5.0 * sqrt(NPE) + 0.5);
1572 if (i < 1) { i = 1; }
1573 if (M < i) { M = i; }
1575 double p = NPE * exp(-NPE) / (double) 1;
1577 for (
int __i = 1; __i != i; ++__i) {
1583 for (
double p0 = 0.0; (p >= p0 || p > precision) && i != M; ++i, p0 = p, p *= NPE / (double) i) {
Time calibration (including definition of sign of time offset).
#define THROW(JException_t, A)
Marco for throwing exception with std::ostream compatible message.
Auxiliary methods for mathematics.
Data structure for PMT parameters.
double sigma_ns
time-over-threshold standard deviation of threshold-band hits [ns]
double QE
relative quantum efficiency
int getType() const
Get type for for time-slewing correction.
double thresholdBand
threshold-band [npe]
double gainSpread
gain spread [unit]
JPMTParameters()
Default constructor.
double riseTime_ns
rise time of analogue pulse [ns]
double TTS_ns
transition time spread [ns]
double threshold
threshold [npe]
double mean_ns
mean time-over-threshold of threshold-band hits [ns]
void setPMTParameters(const JPMTParameters ¶meters)
Set PMT parameters.
double slope
slope [ns/npe]
double PunderAmplified
probability of underamplified hit
bool slewing
time slewing of analogue signal
double saturation
saturation [ns]
PMT signal processor interface.
virtual double getChargeProbability(const double npe, const int NPE) const
Get probability density for given charge.
Exception for accessing a value in a collection that is outside of its range.
file Auxiliary data structures and methods for detector calibration.
JDETECTOR::JTransitTimeGenerator_t getTransitTime
Function object to generate transit time.
const double TIME_OVER_THRESHOLD_NS
Specification for time-over-threshold corresponding to a one photo-electron pulse.
double getChargeProbability(const JPMTSignalProcessorInterface &pmt, const double npe, const double NPE, const double precision=1.0e-4)
Get charge probability convoluted with a Poisson distribution.
double getTimeOverThresholdProbability(const JPMTAnalogueSignalProcessor &pmt, const double tot_ns, const double NPE, const double precision=1.0e-4)
Get time-over-threshold probability convoluted with a Poisson distribution.
double binomial(const size_t n, const size_t k)
Binomial function.
PMT analogue signal processor.
double getUnderamplifiedGain() const
Get gain of underamplified pulses.
double getDecayTime() const
Get decay time.
friend std::istream & operator>>(std::istream &in, JPMTAnalogueSignalProcessor &object)
Read PMT signal from input.
virtual bool applyQE() const override
Apply relative QE.
virtual bool compare(const JPhotoElectron &first, const JPhotoElectron &second) const override
Compare arrival times of photo-electrons.
static double getMaximalRiseTime(const double th)
Get maximal rise time for given threshold.
double getT1() const
Get time at transition point from Gaussian to exponential.
double getUnderamplifiedGainSpread(int NPE) const
Get gain spread of underamplified pulses.
double getGainSpread(int NPE) const
Get gain spread for given number of photo-electrons.
double getIntegralOfChargeProbability(const JThresholdDomain domain, const int NPE) const
Get integral of probability in specific threshold domain.
double decayTime_ns
decay time [ns]
JAmplificationMode
Amplification mode specifiers.
virtual double getRandomTime(const double t_ns) const override
Get randomised time according transit-time distribution.
virtual bool applyThreshold(const double npe) const override
Apply threshold.
virtual double getChargeProbability(const double npe, const int NPE) const override
Get probability density for given charge.
double y1
amplitude at match point [npe]
JAnaloguePulseDomain getToTDomain(const double tot_ns) const
Get time-over-threshold domain.
double getUnderamplifiedGainSpread() const
Get gain spread of underamplified pulses.
double getGain(int NPE) const
Get gain.
static double getTH1()
Get upper threshold for rise time evaluation.
virtual double getRiseTime(const double npe) const override
Get time to reach threshold.
virtual double getNPE(const double tot_ns) const override
Get number of photo-electrons.
double x1
Transition point from a logarithmic to a linear relation between time-over-threshold and number of ph...
double getTimeOverThresholdProbability(const double tot_ns, const int NPE) const
Get probability of having a pulse with specific time-over-threshold.
double getIntegralOfChargeProbability(const double xmin, const double xmax, const int NPE) const
Get integral of probability.
double getIntegralOfTimeOverThresholdProbability(const double Tmin, const double Tmax, const int NPE) const
Get cumulative probability of time-over-threshold distribution.
JAnaloguePulseDomain getChargeDomain(const double npe) const
Get charge domain.
JAnaloguePulseDomain
Analogue pulse domain specifiers.
double getY1() const
Get amplitude at transition point from Gaussian to exponential.
JThresholdDomain getThresholdDomain(const double npe) const
Get threshold domain.
virtual double getThresholdProbability(const int NPE) const override
Probability that a hit survives the threshold of the PMT.
double getRandomChargeUnderAmplified(const int NPE) const
Get randomised charge according to gain and gain spread with an underamplified amplification mode.
double getRandomChargeMixed(const int NPE) const
Get randomised charge according to gain and gain spread with a mixed amplification mode.
virtual double getRandomCharge(const int NPE) const override
Get randomised charge according to gain and gain spread.
JPMTAnalogueSignalProcessor(const JPMTParameters ¶meters=JPMTParameters())
Constructor.
double getChargeProbabilityMixed(const double npe, const double NPE) const
Get probability density for given charge with a mixed amplification mode.
double getDerivativeOfSaturation(const double tot_ns) const
Get derivative of saturation factor.
double getThresholdProbabilityUnderAmplified(const int NPE) const
Probability that a hit survives the threshold of the PMT with an underamplified amplification mode.
JAmplificationMode getAmplificationMode() const
Get amplification mode.
double getIntegralOfChargeProbabilityNominal(const double xmin, const double xmax, const int NPE) const
Get integral of probability with a nominal amplification mode.
double applySaturation(const double tot_ns) const
Get time-over-threshold with saturation.
double getDecayTime(const double npe, const double th) const
Get time to pass from top of analogue pulse to threshold.
double removeSaturation(const double tot_ns) const
Get time-over-threshold without saturation.
double getRiseTime(const double npe, const double th) const
Get time to pass from threshold to top of analogue pulse.
double getThresholdProbabilityNominal(const int NPE) const
Probability that a hit survives the threshold of the PMT with a nominal amplification mode.
double getChargeProbabilityNominal(const double npe, const int NPE) const
Get probability density for given charge with a Nominal amplification mode.
double getAmplitude(const double t1_ns) const
Get amplitude at given time for a one photo-electron pulse.
static double getTH0()
Get lower threshold for rise time evaluation.
double getStartOfLinearisation() const
Get transition point from a model-dependent to linear relation between time-over-threshold and number...
JThresholdDomain
Threshold domain specifiers.
@ ABOVE_THRESHOLD
above threshold
@ BELOW_THRESHOLD
below threshold
@ THRESHOLDBAND
inside threshold band
void setPMTParameters(const JPMTParameters ¶meters)
Set PMT parameters.
void configure()
Configure internal parameters.
double getChargeProbabilityUnderAmplified(const double npe, const int NPE) const
Get probability density for given charge with an underamplified amplification mode.
virtual double getSurvivalProbability(const int NPE) const override
Probability that a hit survives the simulation of the PMT.
double getIntegralOfChargeProbabilityMixed(const double xmin, const double xmax, const int NPE) const
Get integral of probability with a mixed amplification mode.
virtual double getTimeOverThreshold(const double npe) const override
Get time-over-threshold.
double getIntegralOfChargeProbabilityUnderAmplified(const double xmin, const double xmax, const int NPE) const
Get integral of probability with an underamplified amplification mode.
double getGainSpread() const
Get gain spread for given number of photo-electrons.
virtual double getDerivative(const double npe) const override
Get derivative of number of photo-electrons to time-over-threshold with saturation.
double getUnderamplifiedGain(int NPE) const
Get gain of underamplified pulses.
double getThresholdProbabilityMixed(const int NPE) const
Probability that a hit survives the threshold of the PMT with a mixed amplification mode.
double t1
time at match point [ns]
double getRandomChargeNominal(const int NPE) const
Get randomised charge according to gain and gain spread with a nominal amplification mode.
Data structure for single photo-electron.