9#include <ecl/modules/eclEventT0/ECLEventT0Module.h>
15#include <framework/dataobjects/EventT0.h>
18#include <ecl/dataobjects/ECLCalDigit.h>
36 addParam(
"ethresh",
m_ethresh,
"Minimum energy (GeV) for an ECLCalDigit to be used", 0.06);
37 addParam(
"maxDigitT",
m_maxDigitT,
"Maximum absolute time (ns) for an ECLCalDigit to be used", 150.);
38 addParam(
"sigmaScale",
m_sigmaScale,
"Scale factor between dt99 and ECLCalDigit time resolution", 0.15);
57 std::vector<float> tLike;
58 std::vector<float> sigmaLike;
64 float digitT = eclCalDigit.getTime();
65 float dt99 = eclCalDigit.getTimeResolution();
67 tLike.push_back(digitT);
71 itmin = tLike.size() - 1;
75 itmax = tLike.size() - 1;
79 int nLike = tLike.size();
87 std::vector<float> localT0;
88 std::vector<float> localT0Unc;
89 std::vector<float> localquality;
96 localT0.push_back(T0);
97 localT0Unc.push_back(T0Unc);
98 localquality.push_back(0.);
100 }
else if (nLike >= 2) {
104 float minrange = 50.;
105 tmin = tLike[itmin] - 3 * sigmaLike[itmin];
107 tmax = tLike[itmax] + 3 * sigmaLike[itmax];
110 if (tmin >
m_maxT0 - minrange) {
113 }
else if (tmax < minrange -
m_maxT0) {
116 }
else if (tmax - tmin < minrange) {
117 float drange = 0.5 * (minrange + tmin - tmax);
118 tmin = tmin - drange;
119 tmax = tmax + drange;
124 int nhypo = (0.5 + tmax - tmin) /
m_T0bin;
125 float trange = nhypo *
m_T0bin;
126 std::vector<float> t0hypo;
127 for (
int it0 = 0; it0 < nhypo; it0++) {
128 t0hypo.push_back(tmin + (it0 + 0.5)*
m_T0bin);
133 std::vector<float> sigFracVsT0(nhypo, 0.);
134 std::vector<float> chiVsT0(nhypo, 0.);
135 float minChi2 = 99999.;
137 for (
int it0 = 0; it0 < nhypo; it0++) {
139 for (
int iLike = 0; iLike < nLike; iLike++) {
140 if (abs(tLike[iLike] - t0hypo[it0]) < 3.*sigmaLike[iLike]) {n3sig++;}
142 float signalFrac = n3sig / nLike;
143 sigFracVsT0[it0] = signalFrac;
147 for (
int iLike = 0; iLike < nLike; iLike++) {
148 float arg = (tLike[iLike] - t0hypo[it0]) / sigmaLike[iLike];
149 float sigProb = sigFracVsT0[it0] * TMath::Exp(-0.5 * arg * arg) / sigmaLike[iLike] /
sqrt(2.*TMath::Pi()) +
150 (1. - sigFracVsT0[it0]) / trange;
151 chi2 += -2.*TMath::Log(sigProb);
156 if (chi2 < minChi2) {
169 std::vector<float> LHslope(nhypo, 0.);
171 for (
int it0 = 1; it0 < nhypo; it0++) {
172 if (sigFracVsT0[it0 - 1] == sigFracVsT0[it0]) {
173 slope = chiVsT0[it0] - chiVsT0[it0 - 1];
175 LHslope[it0] = slope;
179 std::vector<float> HLslope(nhypo, 0.);
181 for (
int it0 = nhypo - 2; it0 >= 0; it0--) {
182 if (sigFracVsT0[it0] == sigFracVsT0[it0 + 1]) {
183 slope = chiVsT0[it0 + 1] - chiVsT0[it0];
185 HLslope[it0] = slope;
191 float minLocalChi2 = chiVsT0[0];
193 float T0ClosestTo0 = 99999.;
195 std::vector<int> itlocal;
196 for (
int it0 = 1; it0 < nhypo - 1; it0++) {
197 if ((LHslope[it0] < 0. && HLslope[it0] > 0.) || (LHslope[it0] == 0. && HLslope[it0] > 0. && LHslope[it0 - 1] < 0.
198 && HLslope[it0 - 1] == 0.)) {
199 localT0.push_back(t0hypo[it0]);
200 localquality.push_back(chiVsT0[it0]);
201 itlocal.push_back(it0);
202 if (chiVsT0[it0] < minLocalChi2) {
203 minLocalChi2 = chiVsT0[it0];
206 if (abs(t0hypo[it0]) < abs(T0ClosestTo0)) {
207 T0ClosestTo0 = t0hypo[it0];
212 nT0Values = localT0.size();
216 for (
int imin = 0; imin < nT0Values; imin++) {
218 if (itlocal[imin] > 0 && itlocal[imin] < nhypo) {
219 float chiTarget = chiVsT0[itlocal[imin]] + 4.;
220 int ih = itlocal[imin];
221 while (ih < nhypo - 1 and chiVsT0[ih] < chiTarget) {ih++;}
222 int il = itlocal[imin];
223 while (il > 0 and chiVsT0[il] < chiTarget) {il--;};
224 localUnc = (t0hypo[ih] - t0hypo[il]) / 4.;
226 localT0Unc.push_back(localUnc);
237 quality = chiVsT0[itsel];
240 if (itsel > 0 && itsel < nhypo) {
241 float chiTarget = chiVsT0[itsel] + 4.;
243 while (ih < nhypo - 1 and chiVsT0[ih] < chiTarget) {ih++;}
244 float ta = t0hypo[ih - 1];
245 float tb = t0hypo[ih];
246 float ca = chiVsT0[ih - 1];
247 float cb = chiVsT0[ih];
249 if (cb != ca) {th = ta + (tb - ta) * (chiTarget - ca) / (cb - ca);}
251 while (il > 0 and chiVsT0[il] < chiTarget) {il--;}
255 cb = chiVsT0[il + 1];
257 if (cb != ca) {tl = ta + (tb - ta) * (chiTarget - ca) / (cb - ca);}
258 T0Unc = (th - tl) / 4.;
268 for (
int it = 0; it < nT0Values; it++) {
double m_ethresh
minimum energy for ECLCalDigit to be used (0.06 GeV)
StoreObjPtr< EventT0 > m_eventT0
StoreObj EventT0
virtual void initialize() override
Register input and output data.
double m_sigmaScale
scale factor for time resolution (ie dt99) of ECLCalDigit (0.15)
virtual void event() override
Event.
double m_maxDigitT
maximum absolute value of ECLCalDigit time to be used (150 ns)
double m_maxT0
maximum allowed absolute value of T0, in ns (135 ns)
StoreArray< ECLCalDigit > m_eclCalDigitArray
eclCalDigits
double m_T0bin
step size between T0 hypotheses (1 ns)
int m_primaryT0
select which T0 is primary, ie first one reported.
ECLEventT0Module()
Constructor: Sets the description, the properties and the parameters of the module.
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...
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
Abstract base class for different kinds of events.
Structure for storing the extracted event t0s together with its detector and its uncertainty.